如何理解将IP字符串转换为整数的函数式编程代码?

2024-06-17 09:06:51 发布

您现在位置:Python中文网/ 问答频道 /正文

在python的讨论中,我看到了一个函数,用函数编程的方式将IP字符串转换为整数。这是the Link。在

函数在单行中实现。在

def ipnumber(ip):
    return reduce(lambda sum, chunk: sum <<8 | chunk, map(int, ip.split(".")))

但是,我对函数编程没有什么想法。有人能详细解释一下这个功能吗?我对“地图”和“减少”有一定的了解。但我不知道这里的“|”和“chunk”是什么意思。在

谢谢。在


Tags: the函数字符串ipreturndef编程方式
2条回答

|bitwise, logical or

>>> 0 | 1
1
>>> 1 | 1
1

Reduce使用当前运行的总计和map()函数输出的下一个(整数)值调用lambda。因此,它在一个循环中执行以下操作:

^{pr2}$

其中map(int, ip.split("."))将IP地址变成一个整数序列;1.2.3.4变成{}。在

<<是一个bitwise left shift,在本例中为8位:

>>> 1 << 8
256

因此,对于ip地址的每个整数部分,它将值向左移动8个位置,并将地址下一部分的位加到该数字上。在

这很有意义,因为IP地址只不过是一个32位的数字,而字符串表示法将该数字分成4个8位的块,然后“打印”这8个位中每个位的整数值,中间有一个.字符。在

它有助于将每个阶段打印为二进制数:

>>> map(int, '1.2.3.4'.split('.'))
[1, 2, 3, 4]
>>> bin(1)
'0b1'
>>> bin(2)
'0b10'
>>> bin(3)
'0b11'
>>> bin(4)
'0b100'
>>> bin(1 << 8)
'0b100000000'
>>> bin(1 << 8 | 2)
'0b100000010'
>>> bin((1 << 8 | 2) << 8)
'0b10000001000000000'
>>> bin((1 << 8 | 2) << 8 | 3)
'0b10000001000000011'
>>> bin(((1 << 8 | 2) << 8 | 3) << 8)
'0b1000000100000001100000000'
>>> bin(((1 << 8 | 2) << 8 | 3) << 8 | 4)
'0b1000000100000001100000100'

sumchunk是传递给reducelambda函数的参数。|是二进制或运算符。在

事情是这样的:

  • ip.split(".")返回一个字符串列表,每个字符串对应于一段虚线字符串("192.168.0.1"=>;["192", "168", "0", "1"]

  • map将其第一个操作数应用于第二个操作数的每个元素(["192", "168", "0", "1"]=>;[192, 168, 0, 1]);

  • reduce从列表中获取前两个参数,并将lambda应用于它们;然后对lambda的结果和列表的下一个元素再次执行此操作;依此类推。

  • labmda函数(一个在现场定义的匿名函数)执行此操作:获取第一个参数,将其移动8位,并将OR转换为新块;因此,结果的计算方式如下:

    (((192<<8 | 168) << 8 | 0)<<8 | 1) = 192<<24 | 168<<16 | 0<<8 | 1
    

    这正是“虚线形式”所代表的(它只是表示32位无符号整数的简写,这是IPv4中的IP—您可以说它有点像以256为基数表示)

相关问题 更多 >