将数字转换为基数64

问题描述 投票:2回答:1

所以我试图用我发现的这个很棒的项目(在Python 3 without字符串中)编程。

以相反的顺序将36位数字n的6个字符的字符串表示形式返回为基数64,其中64个数字的顺序为:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+

例如,

encode(0) → '000000'
encode(9876543210) → 'gR1iC9'
encode(68719476735) → '++++++'

到目前为止,我的是:

def encode(n):
  SYM = {'0': 0,
         '1': 1,
         '2': 2,
         '3': 3,
         '4': 4,
         '5': 5,
         '6': 6,
         '7': 7,
         '8': 8,
         '9': 9,
         'A': 10,
         'B': 11,
         'C': 12,
         'D': 13,
         'E': 14,
         'F': 15,
         'G': 16,
         'H': 17,
         'I': 18,
         'J': 19,
         'K': 20,
         'L': 21,
         'M': 22,
         'N': 23,
         'O': 24,
         'P': 25,
         'Q': 26,
         'R': 27,
         'S': 28,
         'T': 29,
         'U': 30,
         'V': 31,
         'W': 32,
         'X': 33,
         'Y': 34,
         'Z': 35,
         'a': 36,
         'b': 37,
         'c': 38,
         'd': 39,
         'e': 40,
         'f': 41,
         'g': 42,
         'h': 43,
         'i': 44,
         'j': 45,
         'k': 46,
         'l': 47,
         'm': 48,
         'n': 49,
         'o': 50,
         'p': 51,
         'q': 52,
         'r': 53,
         's': 54,
         't': 55,
         'u': 56,
         'v': 57,
         'w': 58,
         'x': 59,
         'y': 60,
         'z': 61,
         '-': 62,
         '+': 63,}

但是现在我不确定下一步该怎么做。我不想使用字符串和连接等,我想使用模数和标准数论+for/while/ else方法来做到这一点。

我的想法是要定义

r1 = n % 63
r2 = r1 % 63
r3 = r2 % 63
r4 = r3 % 63
r5 = r4 % 63
r6 = r5 % 63

但是我不知道该怎么办。

我应该如何将n转换为基数64?

[最后,我找到新的表示形式后要反转数字,我想我将修改10的幂以隔离每个数字,然后将它们放回原位。

我应该如何进行编程?

python python-3.x encode number-theory
1个回答
2
投票

这里有一些代码可以满足您的需求。 get_digit函数使用一堆if... elif测试将0 <= d <64中的整数d转换为其相应的字符号,然后使用标准的chr函数将该数字转换为实际字符。 encode函数执行实际的余数计算,调用get_digit进行字符转换,然后将结果保存到out列表中。我们将该列表附加'0'个字符以使其长度为6。

def get_digit(d):
    ''' Convert a base 64 digit to the desired character '''
    if 0 <= d <= 9:
        # 0 - 9
        c = 48 + d
    elif 10 <= d <= 35:
        # A - Z
        c = 55 + d
    elif 36 <= d <= 61:
        # a - z
        c = 61 + d
    elif d == 62:
        # -
        c = 45
    elif d == 63:
        # +
        c = 43
    else:
        # We should never get here
        raise ValueError('Invalid digit for base 64: ' + str(d)) 
    return chr(c)

# Test `digit`
print(''.join([get_digit(d) for d in range(64)]))

def encode(n):
    ''' Convert integer n to base 64 '''
    out = []
    while n:
        n, r = n // 64, n % 64
        out.append(get_digit(r))
    while len(out) < 6:
        out.append('0')
    return ''.join(out)

# Test `encode`
for i in (0, 9876543210, 68719476735):
    print(i, encode(i))

输出

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+
0 000000
9876543210 gR1iC9
68719476735 ++++++

由于我们正在使用2的幂的基数,所以可以替代

n, r = n // 64, n % 64

是使用按位运算

n, r = n >> 64, n & 63

速度稍快,但是我想这在这里并没有多大区别,并且先前的代码更具可读性。 OTOH,了解为什么按位版本会产生正确结果会很有用。

© www.soinside.com 2019 - 2024. All rights reserved.