线性代数Python计算:Python的位运算

本文介绍了Python中整数的二进制表示及其位运算,包括按位或、异或、与和非等操作。同时,详细阐述了如何使用位运算分析IPv4地址,分为A、B、C三类,并通过位运算计算网络号和主机号。通过示例程序展示了对给定IP地址进行类型判断和网络号、主机号分析的过程。
摘要由CSDN通过智能技术生成

在这里插入图片描述
Python中整数在机器内部是按按二进制格存储的,每一位非0即1。因此,每一位都构成了布尔代数 ( B , ∨ , ∧ , ¬ ) (B,\vee,\wedge,\neg) (B,,,¬)以及域 ( B , ⊕ , ∧ ) (B,\oplus,\wedge) (B,,),其中 B = { 0 , 1 } B=\{0,1\} B={0,1} ∨ , ∧ , ¬ , ⊕ \vee,\wedge,\neg,\oplus ,,¬,分别表示异或运算。两个整数的 x x x y y y的位运算指的是:若 x x x y y y的二进制位数相同则对应位进行相应的运算,否则对齐最低位,位数少的高位补0,然后对应位进行相应运算。对应各运算的运算符如下表所列:

运算运算结果备注
(1)x|yx和y按位或 ∨ \vee
(2)x^yx和y按位异或 ⊕ \oplus
(3)x&yx和y按位与 ∧ \wedge
(4)~x对x带符号位的补码按位取反后的补码
(5)x<<nx左移n位n必须是非负整数
(6)x>>yx右移n位n必须是非负整数

需要说明的是,

  1. ~x并非对整数x的二进制原码逐位取反,要实现整数原码逐位取反只需对每一位与1作异或运算即可(参见例1-8);
  2. 左移运算表示将整数x向左每移动一个二进制位,右端添加一位0。即x<<n相当于x ⋅ 2 n \cdot 2^n 2n。相仿地,x>>n相当于x / 2 n /2^n /2n

int类对象的函数bit_length计算并返回整数的二进制表达式的长度(位数),例如设a中整数为286,则a.bit_length()将返回9。注意, 2 n − 1 2^n-1 2n1的二进制表达式为 11 ⋯ 1 ⏟ n \underbrace{11\cdots1}_{n} n 111。Python的bin函数将整数转换成二进制表达式串,例如bin(2**8-1)将返回串’0b11111111’。
例1 遵从\emph{TCP/IP}协议的互联网Internet中,每一个节点都有一个IP地址,对IPV4而言,一个IP地址a就是一个32位2进制非负整数。为方便计,通常将此整数的二进制式分成4节,每节8位(1个字节),用点号“.”隔开。例如一个节点的IP地址为整数3232236047,其二进制式为
11000000.10101000.00000010.00001111 \text{11000000.10101000.00000010.00001111} 11000000.10101000.00000010.00001111
第1节的11000000对应十进制整数192,第2节的10101000对应168,第3节的00000010对应 2 2 2,第4节的00001111对应15。在文献中为简短计,常记为
192.168.2.15 \text{192.168.2.15} 192.168.2.15
TCP/IP规定每个IP地址分成网络号和主机号两部分,并将所有 2 32 = 4294967296 2^{32}=4294967296 232=4294967296个IP地址分成{A、B、C、D、E}五类。常用的{A、B、C}三类地址的定义如下:

类别网络号主机号
A第1个字节,取值1~126后3个字节
B前两个字节,第1字节取值128~191后2个字节
C前3个字节,第1个字节取值192~223最后一个字节

路由程序用“掩码”来分析IPV4地址a的类型、网络号和主机号。具体地说,

  1. 用掩码 255.0.0.0 255.0.0.0 255.0.0.0与a计算按位与,然后右移 24 24 24位得到地址的第一个字节取值,以此判断网络类型;
  2. 根据(1)算得的网络类型,设置A型网络掩码m为255.0.0.0,B型网络掩码m为255.255.0.0,C型网络掩码m为255.255.255.0;
  3. 计算a与掩码m的按位与并右移若干位(A类右移24位,B类右移16位,C类右移 8 8 8位)得网络号;
  4. 对由(3)算得的掩码m逐位取反得m1,计算a与m1的按位与算得主机号。

下列程序对给定的表示IPV4地址的整数a判断其类型并分析网络号及主机号。

def ipAnaly(a):
    b32=2**32-1                 #32位1
    m=255<<24                   #掩码255.0.0.0
    t=(a&m)>>24                 #地址的第1个字节
    if 1<=t<=126:               #A类地址
        t1='A'                  #地址类型
        n=t                     #网络号
        m1=m^b32                #掩码255.0.0.0的反码
        p=a&m1                  #主机号
    if 128<=t<=191:             #B类地址
        t1='B'                  #地址类型
        m=(2**16-1)<<16         #掩码255.255.0.0
        n=(a&m)>>16             #网络号
        m1=m^b32                #掩码的反码
        p=a&m1                  #主机号
    if 192<=t<=223:             #C类地址
        t1='C'                  #地址类型
        m=(2**24-1)<<8          #掩码255.255.255.0
        n=(a&m)>>8              #网络号
        m1=m^b32                #掩码的反码
        p=a&m1                  #主机号
    return t1, n, p
a=2005012608                    #地址119.130.16.128
print(ipAnaly(a))
a=2282885253                    #地址136.18.16.133
print(ipAnaly(a))
a=3321996052                    #地址198.1.163.20
print(ipAnaly(a))        

程序的第1~22行定义了用于IP地址分析的函数ipAnaly,该函数仅有一个表示待分析的IP地址的整型参数a。函数体中,第2行用 2 32 − 1 2^{32}-1 2321设置用于原码求反的32位1的整数为b32;第3行用255<<24将掩码m设置为第1个字节全为1,其他全为0,即255.0.0.0,用于分析地址a的第1个字节以判断地址类型;第4行用按位与a&m算出a中第1字节后面三个字节全为0,然后a&m>>24右移24位得a的第1字节值,赋予t;第5~9行、第10~15行、第16~21行的if语句分别就算得的t判断而得的三种地址类型分析计算网络号n和主机号p。以第10~15行的if语句为例加以说明,另外两个情形读者可参考代码的解释信息参照阅读理解。第10行测得地址类型为B,第11行将字符’B’赋予t1;第12行将掩码m置为前两个字节为1,其余全为0,即255.255.0.0;第13行中按位与a&m计算a的前两个字节及后两个为0的字节构成整数,(a&m)>>16则将该整数右移16位,得到a的前两个字节的整数值,赋予网络号n;第14行中按位异或m^b32计算m的按位取反:前两个字节为0后两个字节为1,赋予m1;第15行中按位与a^m1算得a的后两个字节的值,赋予主机号p。
第23~24行、25~26和27~28分别对表示IP地址的整数2005012608(119.130.16.128)、2282885253(136.18.16.133)和3321996052(198.1.163.20)调用函数ipAnaly分析计算地址的类型、网络号及主机号并输出。运行程序,输出

('A', 119, 8523904)
('B', 34834, 4229)
('C', 12976547, 20)

写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!
代码诚可贵,原理价更高。若为AI学,读正版书好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值