9

簡単な質問。Pythonでエンコーダーを検索または作成して、大文字と小文字を使用して数字の文字列を短縮しようとしています。数値文字列は次のようになります。

20120425161608678259146181504021022591461815040210220120425161608667

長さは常に同じです。

私の最初の考えは、大文字と小文字の文字と数字を利用してこの文字列を次のように短縮する簡単なエンコーダーを作成することでした。

a26Dkd38JK

それは完全に恣意的であり、できるだけ明確にしようとしただけです。これを行うには、おそらくすでに組み込まれている、本当に巧妙な方法があると確信しています。たぶん、これは、尋ねるのも恥ずかしい質問です。

また、短縮された文字列を取得して、より長い数値に戻すことができる必要があります。何かを書いてコードを投稿する必要がありますか、それともこれはPythonの組み込み関数である1行で、すでに知っておく必要がありますか?

ありがとう!

4

4 に答える 4

10

これはかなり良い圧縮です:

import base64

def num_to_alpha(num):
    num = hex(num)[2:].rstrip("L")

    if len(num) % 2:
        num = "0" + num

    return base64.b64encode(num.decode('hex'))

最初に整数をバイト文字列に変換し、次にbase64でエンコードします。デコーダーは次のとおりです。

def alpha_to_num(alpha):
    num_bytes = base64.b64decode(alpha)
    return int(num_bytes.encode('hex'), 16)

例:

>>> num_to_alpha(20120425161608678259146181504021022591461815040210220120425161608667)
'vw4LUVm4Ea3fMnoTkHzNOlP6Z7eUAkHNdZjN2w=='
>>> alpha_to_num('vw4LUVm4Ea3fMnoTkHzNOlP6Z7eUAkHNdZjN2w==')
20120425161608678259146181504021022591461815040210220120425161608667
于 2012-04-26T01:38:55.857 に答える
10

カスタム(に基づいていないbase64)であるが、より短い出力を生成する2つの関数があります。

chrs = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
l = len(chrs)

def int_to_cust(i):
    result = ''
    while i:
        result = chrs[i % l] + result
        i = i // l
    if not result:
        result = chrs[0]
    return result

def cust_to_int(s):
    result = 0
    for char in s:
        result = result * l + chrs.find(char)
    return result

そして結果は次のとおりです。

>>> int_to_cust(20120425161608678259146181504021022591461815040210220120425161608667)
'9F9mFGkji7k6QFRACqLwuonnoj9SqPrs3G3fRx'
>>> cust_to_int('9F9mFGkji7k6QFRACqLwuonnoj9SqPrs3G3fRx')
20120425161608678259146181504021022591461815040210220120425161608667L

変数に他の文字を追加すると、生成された文字列を短くすることもできchrsます。

于 2012-04-26T02:04:20.820 に答える
1

'クラス'でそれを行います:

VALID_CHRS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
BASE = len(VALID_CHRS)
MAP_CHRS = {k: v
            for k, v in zip(VALID_CHRS, range(BASE + 1))}


class TinyNum:
    """Compact number representation in alphanumeric characters."""

    def __init__(self, n):
        result = ''
        while n:
            result = VALID_CHRS[n % BASE] + result
            n //= BASE
        if not result:
            result = VALID_CHRS[0]
        self.num = result

    def to_int(self):
        """Return the number as an int."""
        result = 0
        for char in self.num:
            result = result * BASE + MAP_CHRS[char]
        return result

使用例:

>> n = 4590823745
>> tn = TinyNum(a)
>> print(n)
4590823745
>> print(tn.num)
50GCYh
print(tn.to_int())
4590823745

Tadeckの回答に基づく。)

于 2019-11-18T15:42:50.460 に答える
0
>>> s="20120425161608678259146181504021022591461815040210220120425161608667"
>>> import base64, zlib
>>> base64.b64encode(zlib.compress(s))
'eJxly8ENACAMA7GVclGblv0X4434WrKFVW5CtJl1HyosrZKRf3hL5gLVZA2b'
>>> zlib.decompress(base64.b64decode(_))
'20120425161608678259146181504021022591461815040210220120425161608667'

したがって、zlibは数字の文字列を圧縮するのにあまり賢くありません:(

于 2012-04-26T01:55:03.963 に答える