Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按位操作,移动进位_Python_Bit Manipulation - Fatal编程技术网

Python 按位操作,移动进位

Python 按位操作,移动进位,python,bit-manipulation,Python,Bit Manipulation,目标是能够做到: struct.pack('!H', x) 但是,如果x大于65535,那么由于明显的原因,这将失败。 我不是一个进行位操作的向导,但我知道好的,所以这不是最优雅的解决方案,也不确定它是否准确,但至少不会破坏struct.pack() 根据@Tryph提出的一个简单问题,我提出了以下解决方案: from struct import unpack, pack from binascii import * even_bytes_string = b'\x45\x00\x00\x3

目标是能够做到:

struct.pack('!H', x)
但是,如果
x
大于
65535
,那么由于明显的原因,这将失败。

我不是一个进行位操作的向导,但我知道
好的,所以这不是最优雅的解决方案,也不确定它是否准确,但至少不会破坏
struct.pack()

根据@Tryph提出的一个简单问题,我提出了以下解决方案:

from struct import unpack, pack
from binascii import *

even_bytes_string = b'\x45\x00\x00\x3c\x1c\x46\x40\x00\x40\x06\xac\x10\x0a\x63\x‌​ac\x10\x0a\x0c'
result = None
for i in range(0, len(even_bytes_string)-1,2):
    if not result:
        result = unpack('!H', even_bytes_string[i:i+2])[0]
        continue

    result += unpack('!H', even_bytes_string[i:i+2])[0]
    if result > 65535:
        tmp = pack('!I', result)
        carry = unpack('!H', tmp[:2])[0]
        result = unpack('!H', tmp[2:])[0]+carry

    print(result)
    print(pack('!H', result))

简单地将较大的数字视为
Int
而不是
Short
,这使我能够将两个前置字节作为进位,并将它们添加到后面两个字节的顶部。它并不优雅,但可能有效?

过程只是
(x&0xFFFF)+(x>>16)
如果最后一位是1而不是0,你会怎么想?@Tryph我刚刚意识到我应该简单地将携带位(可能是多个)添加到两组字节中。所以我的问题需要更新。也许我可以使用
carry=struct.pack(“!I',result)[:2]
?同样,seams有点不切实际,但比转换为二进制表示并进行字符串操作要好!And、shift或@TORX首先在Python中添加这两个数字(整数精度将根据需要进行扩展)。然后,在您引用的页面上,看起来示例只做了
(x&0xFF)+(x>>16)
通过在我的头脑中进行数学运算,使用我的解决方案和您的解决方案,手动跟踪我期望的值-它们都得出了相同的结论。当查看tcpdump时,它似乎是一个工作的网络校验和头,所以我对这个更高效的解决方案非常满意!非常感谢你的回答,我甚至看到了为什么这会起作用的逻辑:)
from struct import unpack, pack
from binascii import *

even_bytes_string = b'\x45\x00\x00\x3c\x1c\x46\x40\x00\x40\x06\xac\x10\x0a\x63\x‌​ac\x10\x0a\x0c'
result = None
for i in range(0, len(even_bytes_string)-1,2):
    if not result:
        result = unpack('!H', even_bytes_string[i:i+2])[0]
        continue

    result += unpack('!H', even_bytes_string[i:i+2])[0]
    if result > 65535:
        tmp = pack('!I', result)
        carry = unpack('!H', tmp[:2])[0]
        result = unpack('!H', tmp[2:])[0]+carry

    print(result)
    print(pack('!H', result))
def addwrap16( a, b ):
    c = a + b
    w = ( c & 0xFFFF ) + ( c >> 16 )
    print(' {:04x} ->  {:016b}'.format(a, a))
    print(' {:04x} ->  {:016b}'.format(b, b))
    print('{:05x} -> {:017b}'.format(c, c))
    print(' {:04x} ->  {:016b}'.format(w, w))
    print('')
    return w

import struct, functools
even_bytes_string = b'\x45\x00\x00\x3c\x1c\x46\x40\x00\x40\x06\xac\x10\x0a\x63\xac\x10\x0a\x0c'
vals = struct.unpack( '!' + 'H' * ( len( even_bytes_string ) // 2 ), even_bytes_string )
result = functools.reduce(addwrap16, vals)
 4500 ->  0100010100000000
 003c ->  0000000000111100
0453c -> 00100010100111100
 453c ->  0100010100111100

 453c ->  0100010100111100
 1c46 ->  0001110001000110
06182 -> 00110000110000010
 6182 ->  0110000110000010

 6182 ->  0110000110000010
 4000 ->  0100000000000000
0a182 -> 01010000110000010
 a182 ->  1010000110000010

 a182 ->  1010000110000010
 4006 ->  0100000000000110
0e188 -> 01110000110001000
 e188 ->  1110000110001000

 e188 ->  1110000110001000
 ac10 ->  1010110000010000
18d98 -> 11000110110011000
 8d99 ->  1000110110011001

 8d99 ->  1000110110011001
 0a63 ->  0000101001100011
097fc -> 01001011111111100
 97fc ->  1001011111111100

 97fc ->  1001011111111100
 ac10 ->  1010110000010000
1440c -> 10100010000001100
 440d ->  0100010000001101

 440d ->  0100010000001101
 0a0c ->  0000101000001100
04e19 -> 00100111000011001
 4e19 ->  0100111000011001