2017-10-15 14 views
2

그래서 6 문자의 64 진수를 디코딩하는 프로그램을 작성하려고합니다. 64 개 개의 숫자 순이고문자열에서 숫자로 변환

복귀 6 문자열의 역순베이스 64 번호로 표시되는 36- 비트 수 : 여기서

문제 문이다ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz- +

디코드 ('000000') 0

012,351,641 → 68719476735

디코드 ('gR1iC9')

디코드 ('++++++') → 나는 문자열없이이 일을하고 싶습니다.

다음 함수의 역을 생성하는 것이 작업을 수행하는 가장 쉬운 방법 : this 페이지에서 실제로 오후 2Ring로부터

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

.

이 프로그램의 역관계는 어떻게 작성합니까?

스타트는 :

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

아니요, 들여 쓰기가 손실되기 때문에 주석에 여러 줄의 파이썬 코드를 게시하지 마십시오.하지만 어쨌든, 당신의 코드는 질문 자체의 본체에 속해 있습니다. 주석은 단지 당신이 당신의 질문을 명확히하고 개선하는데 도움이 될 것입니다. –

답변

1

여기서 역 동작을 수행하는 새로운 코드 my old code 결합하는 프로그램.

inv_get_digit 함수에 구문 오류가 있습니다. elif 줄 끝에 콜론을 둡니다. c은 이미 문자열이므로 str(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'를 사용했고, 더 의미있는 이름을 찾기에는 너무 게을 렀습니다. ;) 비슷하게, char에 대해서는'c'를 사용하고 숫자에 대해서는'd'를 사용했습니다. 일반적으로 더 자세한 설명이 포함 된 이름을 사용하는 것이 좋은 생각이지만, 무슨 일이 벌어지고 있는지 분명히 알기 쉽게 짧은 이름을 사용하는 것이 좋습니다. 물론, 작가에게 명백한 것은 항상 독자에게 분명하지 않을 수도 있습니다. ;) –