如果我有一对IP地址,如:
IP1="168.2.65.33"
IP2="192.4.2.55"
Run Code Online (Sandbox Code Playgroud)
我想将每对编码为64位值,以便前32位是第一个IP地址,第二个是第二个IP地址.然后,我希望能够将64位值保存到文件中,以便我可以将其读回并恢复两个IP地址.
目的是节省空间.
是否可以在python中执行此操作?
不要担心以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)