python标记编码 字符串转换成数字_Python:将字母数字字符串可逆地编码为整数...

假设字符集仅为字母数字,即a-z a-z 0-9,则每个字符需要6位。因此,使用8位字节编码理论上是对内存的低效使用。在

此答案将输入字节转换为6位整数序列。它使用位操作将这些小整数编码为一个大整数。这是否真的转化为现实世界中的存储效率是由^{}来衡量的,对于较大的字符串更可能如此。在

此实现可自定义用于选择字符集的编码。例如,如果您只使用string.ascii_lowercase(5位)而不是string.ascii_uppercase + string.digits(6位),则编码将相应地高效。在

单元测试也包括在内。在import string

class BytesIntEncoder:

def __init__(self, chars: bytes = (string.ascii_letters + string.digits).encode()):

num_chars = len(chars)

translation = ''.join(chr(i) for i in range(1, num_chars + 1)).encode()

self._translation_table = bytes.maketrans(chars, translation)

self._reverse_translation_table = bytes.maketrans(translation, chars)

self._num_bits_per_char = (num_chars + 1).bit_length()

def encode(self, chars: bytes) -> int:

num_bits_per_char = self._num_bits_per_char

output, bit_idx = 0, 0

for chr_idx in chars.translate(self._translation_table):

output |= (chr_idx << bit_idx)

bit_idx += num_bits_per_char

return output

def decode(self, i: int) -> bytes:

maxint = (2 ** self._num_bits_per_char) - 1

output = bytes(((i >> offset) & maxint) for offset in range(0, i.bit_length(), self._num_bits_per_char))

return output.translate(self._reverse_translation_table)

# Test

import itertools

import random

import unittest

class TestBytesIntEncoder(unittest.TestCase):

chars = string.ascii_letters + string.digits

encoder = BytesIntEncoder(chars.encode())

def _test_encoding(self, b_in: bytes):

i = self.encoder.encode(b_in)

self.assertIsInstance(i, int)

b_out = self.encoder.decode(i)

self.assertIsInstance(b_out, bytes)

self.assertEqual(b_in, b_out)

# print(b_in, i)

def test_thoroughly_with_small_str(self):

for s_len in range(4):

for s in itertools.combinations_with_replacement(self.chars, s_len):

s = ''.join(s)

b_in = s.encode()

self._test_encoding(b_in)

def test_randomly_with_large_str(self):

for s_len in range(256):

num_samples = {s_len <= 16: 2 ** s_len,

16 < s_len <= 32: s_len ** 2,

s_len > 32: s_len * 2,

s_len > 64: s_len,

s_len > 128: 2}[True]

# print(s_len, num_samples)

for _ in range(num_samples):

b_in = ''.join(random.choices(self.chars, k=s_len)).encode()

self._test_encoding(b_in)

if __name__ == '__main__':

unittest.main()

使用示例:

^{pr2}$

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值