以64位编码两个ipv4地址

ele*_*ora 1 python

如果我有一对IP地址,如:

IP1="168.2.65.33"
IP2="192.4.2.55"
Run Code Online (Sandbox Code Playgroud)

我想将每对编码为64位值,以便前32位是第一个IP地址,第二个是第二个IP地址.然后,我希望能够将64位值保存到文件中,以便我可以将其读回并恢复两个IP地址.

目的是节省空间.

是否可以在python中执行此操作?

Jon*_*art 5

不要担心以64位编码它们.IPv4地址是32位(4字节).如果将其中两个写入文件,则其大小为8个字节.

使用socket.inet_aton一个人类可读的IP地址转换成字符串来打包二进制原始4字节的字符串:

import socket
ip_addrs = ["168.2.65.33", "192.4.2.55"]

with open('data.out', 'wb') as f:
    for ip in ip_addrs:
        raw = socket.inet_aton(ip)
        f.write(raw)
Run Code Online (Sandbox Code Playgroud)

结果:

$ hexdump -Cv data.out 
00000000  a8 02 41 21 c0 04 02 37                           |..A!...7|
00000008
Run Code Online (Sandbox Code Playgroud)

互补转换函数socket.inet_ntoa将打包的4字节字符串转换回人类可读的IP地址.


以下是编写和阅读它们的示例:

import socket

ip_pairs = [
    ('1.1.1.1', '1.1.1.2'),
    ('2.2.2.2', '2.2.2.3'),
    ('3.3.3.3', '3.3.3.4'),
]

# Write them out
with open('data.out', 'wb') as f:
    for ip1, ip2 in ip_pairs:
        raw = socket.inet_aton(ip1) + socket.inet_aton(ip2)
        f.write(raw)

def read_with_eof(f, n):
    res = f.read(n)
    if len(res) != n:
        raise EOFError
    return res

# Read them back in
result = []
with open('data.out', 'rb') as f:
    while True:
        try:
            ip1 = socket.inet_ntoa(read_with_eof(f, 4))
            ip2 = socket.inet_ntoa(read_with_eof(f, 4))
            result.append((ip1, ip2))
        except EOFError:
            break

print 'Input:', ip_pairs
print 'Result:', result
Run Code Online (Sandbox Code Playgroud)

输出:

$ python pairs.py 
Input: [('1.1.1.1', '1.1.1.2'), ('2.2.2.2', '2.2.2.3'), ('3.3.3.3', '3.3.3.4')]
Result: [('1.1.1.1', '1.1.1.2'), ('2.2.2.2', '2.2.2.3'), ('3.3.3.3', '3.3.3.4')]
Run Code Online (Sandbox Code Playgroud)