2017-10-15 146 views
2

因此,我正在嘗試編寫一個程序來解碼6個字符的base-64數字。從字符串轉換爲數字

這是問題所在語句:

返回表示爲由6個字符的字符串s以相反的順序鹼-64編號的36比特的數,其中的64個數字的順序是:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz- +

解碼( '000000')→0

解碼( 'gR1iC9')→

解碼( '++++++')→68719476735

我想這樣做不附帶任何條件。

這樣做將創建下列函數的反函數的最簡單方法:

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,, 68719476735): 
    print(i, encode(i)) 

輸出

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+ 
0 000000 
gR1iC9 
68719476735 ++++++ 

裏面居然從下午2Ring是this頁。

我該如何寫這個程序的逆向?

甲開始:

get_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 = 63 
    elif c == '-': 
     d = 62 
    else: 
     raise ValueError('Invalid Input' + str(c)) 
    return d 


def decode(n): 

    out = [] 
    while n: 
     n, r= n % 10, n ** (6-len(str)) 
     out.append(get_digit(r)) 
    while len(out) < 10: 
     out.append('0') 
    return ''.join(out) 
+0

請嘗試自己編寫一些代碼。正如我所說[這裏](https://stackoverflow.com/questions/46739875/converting-a-number-to-base-64-in-python/46740374#comment80448645_46740374),第一步是反轉'get_digit',我給你一個提示如何做到這一點。 –

+0

我編輯了我的帖子以反映您的評論。我沒有在評論中發佈新代碼,因爲格式有偏差。除非這樣更好? –

+0

不,不要在註釋中張貼多行Python代碼,因爲縮進會丟失。但無論如何,你的代碼屬於問題本身,評論只是爲了幫助你澄清和改進你的問題。 –

回答

1

下面是結合my old code一些新的代碼來執行逆操作的程序。

您的inv_get_digit函數中出現語法錯誤:您將冒號從elif行的末尾離開。而且不需要做str(c),因爲c已經是一個字符串了。

恐怕你的decode功能沒有多大意義。它應該將一個字符串作爲輸入並返回一個整數。請參閱下面的工作版本。

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,, 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 
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+ 

Testing inv_get_digit 
True 

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

Testing decode 
000000 0 True 
gR1iCTrue 
++++++ 68719476735 True 
+0

啊,再一次,謝謝。一個簡單的問題,爲什麼我們必須用's'作爲參數? –

+1

@JustAMathematician無後顧之憂。我們可以稱之爲'decode'的任何我們喜歡的參數。我只是用's',因爲它是「字符串」的助記符,我懶得想出一個更有意義的名字。 ;)同樣,我使用'c'作爲char,'d'作爲數字。一般來說,使用更長的描述性名稱是一個好主意,但在明顯發生的情況下使用短名稱也可以。當然,對於作者來說,顯而易見的東西對於讀者來說並不總是很明顯。 ;) –