第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python:將字母數(shù)字字符串可逆地編碼為整數(shù)

Python:將字母數(shù)字字符串可逆地編碼為整數(shù)

開滿天機 2021-08-24 18:11:11
我想將字符串(由字母數(shù)字字符組成)轉(zhuǎn)換為整數(shù),然后將此整數(shù)轉(zhuǎn)換回字符串:string --> int --> string換句話說,我想用整數(shù)表示一個字母數(shù)字字符串。我找到了一個可行的解決方案,我將其包含在答案中,但我認為這不是最佳解決方案,而且我對其他想法/方法感興趣。請不要僅僅因為已經(jīng)存在很多類似的問題而將其標記為重復(fù),我特別想要一種將字符串轉(zhuǎn)換為整數(shù)的簡單方法,反之亦然。這應(yīng)該適用于包含字母數(shù)字字符的字符串,即包含數(shù)字和字母的字符串。
查看完整描述

3 回答

?
侃侃爾雅

TA貢獻1801條經(jīng)驗 獲得超16個贊

回想一下,字符串可以編碼為字節(jié),然后可以編碼為整數(shù)。然后可以反轉(zhuǎn)編碼以獲取字節(jié)后跟原始字符串。


此編碼器用于binascii生成與charel-f 的答案中相同的整數(shù)編碼。我相信它是相同的,因為我對其進行了廣泛的測試。


from binascii import hexlify, unhexlify


class BytesIntEncoder:


    @staticmethod

    def encode(b: bytes) -> int:

        return int(hexlify(b), 16) if b != b'' else 0


    @staticmethod

    def decode(i: int) -> int:

        return unhexlify('%x' % i) if i != 0 else b''

如果您使用的是 Python <3.6,請刪除可選的類型注釋。


快速測試:


>>> s = 'Test123'

>>> b = s.encode()

>>> b

b'Test123'


>>> BytesIntEncoder.encode(b)

23755444588720691

>>> BytesIntEncoder.decode(_)

b'Test123'

>>> _.decode()

'Test123'


查看完整回答
反對 回復(fù) 2021-08-24
?
慕后森

TA貢獻1802條經(jīng)驗 獲得超5個贊

假設(shè)字符集只是字母數(shù)字,即 az AZ 0-9,這需要每個字符 6 位。因此,使用 8 位字節(jié)編碼在理論上是對內(nèi)存的低效使用。


此答案將輸入字節(jié)轉(zhuǎn)換為 6 位整數(shù)序列。它使用按位運算將這些小整數(shù)編碼為一個大整數(shù)。這是否真的轉(zhuǎn)化為現(xiàn)實世界的存儲效率是由 來衡量的sys.getsizeof,對于更大的字符串更有可能。


此實現(xiàn)自定義了字符集選擇的編碼。例如,如果您只使用string.ascii_lowercase(5 位)而不是string.ascii_uppercase + string.digits(6 位),則編碼將相應(yīng)地高效。


單元測試也包括在內(nèi)。


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()

用法示例:


>>> encoder = BytesIntEncoder()

>>> s = 'Test123'

>>> b = s.encode()

>>> b

b'Test123'


>>> encoder.encode(b)

3908257788270

>>> encoder.decode(_)

b'Test123'


查看完整回答
反對 回復(fù) 2021-08-24
  • 3 回答
  • 0 關(guān)注
  • 317 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號