2016-09-30 4 views
0

나는 Swift를 스스로 가르치는 것처럼 Base32 디코딩을 구현하려고하는데,이 언어로 바이트 레벨 이하로 갈 수 없다. UInt8을 5 비트로 잘라 내서 Data 객체에 추가하면 편리 할 것입니다. 출력 base32에서 데이터의 진수 표현을 작동Swift에서 UInt8 변수에서 N 비트를 얻는 방법은 무엇입니까?

def base32_decode(secret): 
    b32alphabet = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567") 
    b32v = [b32alphabet.index(x) for x in secret if x != '='] 
    t1 = ["{0:0>5}".format(bin(v)[2:]) for v in b32v] 
    t2 = ''.join(t1) 
    t3 = textwrap.wrap(t2,8) 
    t4 = [int(v, 2) for v in t3 if len(v) == 8] 
    t5 = ''.join(["{0:0>2}".format(hex(v)[2:]) for v in t4]) 

:

나는 파이썬으로 작성된이 기능을 가지고있다. Swift에서 이것을 복제하고 싶었습니다 (16 진수로 변환하지는 않았지만). 그러나 나는 이것을 멀리 가지고 있습니다 :

func base32decode(string: String) -> Data 
{ 
    let b32a: Array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7"] 
    let complete: NSMutableData = NSMutableData() 

    var b32v: Array<UInt8> = [] 

    for c in string.characters 
    { 
     let index = b32a.index(of: String(c))! 
     b32v.append(UInt8(index)) // Need to append only the 5 LSB 
    } 

    // Return b32v as base 32 decoded data 
... 

쉬운 방법이 있습니까? Google을 통해 아무 것도 찾을 수 없습니다.

답변

4

는 스위프트 는 바이트의 일부를 추출하기 위해 사용될 수있는 비트 조작 연산자 (|, &, <<, >>)가 (그 여부 "쉽게"인지 확실히 의견 기반).

귀하의 파이썬 코드는 먼저 모든 이진 숫자 문자열 을 만든 다음 8 비트 부분으로 분할하고 16 진수 값으로 변환합니다.

다음은 중간 문자열 을 사용하지 않는 가능한 구현입니다. 대신 디코드 된 비트는 정수로 에 누적되고 8 비트가 수집 되 자마자 결과 배열에 이 추가됩니다.

func base32decode(string: String) -> Data { 
    let b32a = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".characters) 
    var b32v: [UInt8] = [] 
    var accum = 0 
    var bits = 0 // # of valid bits in `accum` 
    for c in string.characters { 
     if let index = b32a.index(of: c) { 
      accum = (accum << 5) | index 
      bits += 5 
      if bits >= 8 { 
       b32v.append(UInt8(truncatingBitPattern: accum >> (bits - 8))) 
       bits -= 8 
      } 
     } 
    } 
    return Data(bytes: b32v) 
} 

예 : ("! 안녕하세요"입니다)

print(base32decode(string: "JBSWY3DPEB3W64TMMQQQ") as NSData) 
// <48656c6c 6f20776f 726c6421> 

. 그 함수

재미있는 부분 index 좌측으로 5 개소와 세트 최저 5 비트로 accum 모든 비트 이동

accum = (accum << 5) | index 

을하고,

b32v.append(UInt8(truncatingBitPattern: accum >> (bits - 8))) 

가 추가 된 배열에 대한 가장 왼쪽의 8 개의 유효한 비트는 accum입니다.