且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在base-64中从字符串转换为数字

更新时间:2023-02-03 08:55:12

这是一个结合了

Here's a program that combines my old code with some new code to perform the inverse operations.

inv_get_digit函数中存在语法错误:您将冒号放在elif行的末尾.无需执行str(c),因为c已经是字符串.

You have a syntax error in your inv_get_digit function: you left the colon off the end of an elif line. And there's no need to do str(c), since c is already a string.

恐怕您的decode函数没有多大意义.应该以字符串作为输入并返回一个整数.请在下面查看可用的版本.

I'm afraid that your decode function doesn't make much sense. It's supposed to take a string as input and return an integer. Please see a working version below.

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)

print('Testing get_digit') 
digits = ''.join([get_digit(d) for d in range(64)])
print(digits)

def inv_get_digit(c):
    if '0' <= c <= '9':
        d = ord(c) - 48
    elif 'A' <= c <= 'Z':
        d = ord(c) - 55
    elif 'a' <= c <= 'z':
        d = ord(c) - 61
    elif c == '-':
        d = 62
    elif c == '+':
        d = 63
    else:
        raise ValueError('Invalid input: ' + c)
    return d

print('\nTesting inv_get_digit') 
nums = [inv_get_digit(c) for c in digits]
print(nums == list(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)

print('\nTesting encode')
numdata = (0, 9876543210, 68719476735)
strdata = []
for i in numdata:
    s = encode(i)
    print(i, s)
    strdata.append(s)

def decode(s):
    out = []
    n = 0
    for c in reversed(s):
        d = inv_get_digit(c)
        n = 64 * n + d
    return n

print('\nTesting decode')
for s, oldn in zip(strdata, numdata):
    n = decode(s)
    print(s, n, n == oldn)

输出

Testing get_digit
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+

Testing inv_get_digit
True

Testing encode
0 000000
9876543210 gR1iC9
68719476735 ++++++

Testing decode
000000 0 True
gR1iC9 9876543210 True
++++++ 68719476735 True