python long转int_将python long / int转换为固定大小的字节数组

I'm trying to implement RC4 and DH key exchange in python. Problem is that I have no idea about how to convert the python long/int from the key exchange to the byte array I need for the RC4 implementation. Is there a simple way to convert a long to the required length byte array?

Update: forgot to mention that the numbers I'm dealing with are 768 bit unsigned integers.

解决方案

I haven't done any benchmarks, but this recipe "works for me".

The short version: use '%x' % val, then unhexlify the result. The devil is in the details, though, as unhexlify requires an even number of hex digits, which %x doesn't guarantee. See the docstring, and the liberal inline comments for details.

from binascii import unhexlify

def long_to_bytes (val, endianness='big'):

"""

Use :ref:`string formatting` and :func:`~binascii.unhexlify` to

convert ``val``, a :func:`long`, to a byte :func:`str`.

:param long val: The value to pack

:param str endianness: The endianness of the result. ``'big'`` for

big-endian, ``'little'`` for little-endian.

If you want byte- and word-ordering to differ, you're on your own.

Using :ref:`string formatting` lets us use Python's C innards.

"""

# one (1) hex digit per four (4) bits

width = val.bit_length()

# unhexlify wants an even multiple of eight (8) bits, but we don't

# want more digits than we need (hence the ternary-ish 'or')

width += 8 - ((width % 8) or 8)

# format width specifier: four (4) bits per hex digit

fmt = '%%0%dx' % (width // 4)

# prepend zero (0) to the width, to zero-pad the output

s = unhexlify(fmt % val)

if endianness == 'little':

# see http://stackoverflow.com/a/931095/309233

s = s[::-1]

return s

...and my nosetest unit tests ;-)

class TestHelpers (object):

def test_long_to_bytes_big_endian_small_even (self):

s = long_to_bytes(0x42)

assert s == '\x42'

s = long_to_bytes(0xFF)

assert s == '\xff'

def test_long_to_bytes_big_endian_small_odd (self):

s = long_to_bytes(0x1FF)

assert s == '\x01\xff'

s = long_to_bytes(0x201FF)

assert s == '\x02\x01\xff'

def test_long_to_bytes_big_endian_large_even (self):

s = long_to_bytes(0xab23456c8901234567)

assert s == '\xab\x23\x45\x6c\x89\x01\x23\x45\x67'

def test_long_to_bytes_big_endian_large_odd (self):

s = long_to_bytes(0x12345678901234567)

assert s == '\x01\x23\x45\x67\x89\x01\x23\x45\x67'

def test_long_to_bytes_little_endian_small_even (self):

s = long_to_bytes(0x42, 'little')

assert s == '\x42'

s = long_to_bytes(0xFF, 'little')

assert s == '\xff'

def test_long_to_bytes_little_endian_small_odd (self):

s = long_to_bytes(0x1FF, 'little')

assert s == '\xff\x01'

s = long_to_bytes(0x201FF, 'little')

assert s == '\xff\x01\x02'

def test_long_to_bytes_little_endian_large_even (self):

s = long_to_bytes(0xab23456c8901234567, 'little')

assert s == '\x67\x45\x23\x01\x89\x6c\x45\x23\xab'

def test_long_to_bytes_little_endian_large_odd (self):

s = long_to_bytes(0x12345678901234567, 'little')

assert s == '\x67\x45\x23\x01\x89\x67\x45\x23\x01'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值