如何对字符串按位取反后通过socket发送得到指定TCP数据包
问题原因
你原有代码有两个核心错误,导致结果和预期不符:
- 字符转二进制时没有固定补全8位:单个ASCII字符占1字节(8个二进制位),原写法
format(ord(x), 'b')会自动省略高位前导0,比如字符'1'的二进制是00110001,用该写法只会得到6位长度的110001,拼接后整体二进制串长度错位,取反结果自然不对。 - 取反后未转换为原始字节类型:Python3中
socket.sendall仅接收bytes类型参数,直接传递由'0'/'1'组成的字符串要么运行报错,要么实际发送的是字符'0'和'1'本身的ASCII编码值,完全不是你预期的二进制字节流。
修正方案
不需要手动做二进制字符串的拼接、翻转操作,直接在字节层面做按位取反效率最高,结果也完全匹配你给出的预期字节序列ce 8e cd 88 cc 9a cb 8d:
s = '1q2w3e4r' # 1. 将字符串编码为ASCII字节串,每个字节和0xff异或实现单字节按位取反 # 用^0xff是因为Python整数带符号,直接~会得到负数,和0xff按位与可提取低8位的正确无符号单字节值 inverted_data = bytes( (b ^ 0xff) for b in s.encode('ascii') ) # 2. 直接发送字节对象即可 socket.sendall(inverted_data)
你可以自行打印inverted_data.hex()验证,输出为ce8ecd88cc9acb8d,和预期的TCP载荷完全一致。
如果你一定要沿用二进制字符串的实现逻辑,需要补全固定8位长度、最后转成字节,修正后写法如下(不推荐,执行效率更低):
s = '1q2w3e4r' stbin = '' # 转二进制时固定补0到8位长度 stbin = ''.join(format(ord(x), '08b') for x in s) # 按位取反 stbin = ''.join('1' if x == '0' else '0' for x in stbin) # 每8位切割转成整数,再拼成字节串 inverted_data = bytes( int(stbin[i:i+8], 2) for i in range(0, len(stbin), 8) ) socket.sendall(inverted_data)
内容的提问来源于stack exchange,提问作者sqgun
相关产品推荐
相关产品推荐

