Python - Base64 Decoder, Encoder ( import 없이 )

보기·2022년 5월 20일
0

algorithm

목록 보기
1/1

Base64 Convert

Encoding(Text to Base64)

  • ASCII -> Bit Pattern -> Base64 Expression

1. Text( str ) -> Ascii( List[int] )

  • Text(string)을 ascii 코드로 변환한다
    • [ord(s) for s in text]

2. Ascii( List[int] ) -> binary( List[str] )

  • Ascii code로 변환된 값들을 binary 값으로 변환한다
    • [bin(ord(s)) for s in text]

3. binary( List[str] ) -> bit pattern(str)

  • binary를 연결해서 bit pattern으로 만들기 위해 bin 한 결과의 앞부분을 정리한다. ( ex> '0b1001' -> '1001' )
    • [bin(ord(s))[2:] for s in text]
  • Base64 형식으로 변환하기 위해 8bit 크기의 chunk로 만든다
    • [bin(ord(s)[2:].zfill(8) for s in text]
  • 변환된 결과를 하나의 String으로 join한다
    • ''.join([bin(ord(s)[2:].zfill(8) for s in text])

중간 저장 & Hash Table 생성

bit_pattern = ''.join([bin(ord(s)[2:].zfill(8) for s in text])
table = {i: s for i, s in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')}

4. bit pattern(str) -> base64 code( List[int] )

  • bit 패턴을 base64 테이블의 값으로 치환하기 위해 6bit 크기의 chunk로 순회한다

    • [bit_pattern[i:i + 6] for i in range(0, len(bit_pattern), 6]
  • chunk를 int로 변환한다

    • [int(bit_pattern[i:i + 6], 2) for i in range(0, len(bit_pattern), 6]

5. base64 code( List[int] ) -> base64( str )

  • hash 테이블을 사용해 base64 code를 base64 문자열로 변환한다
    • [table[int(bit_pattern[i:i + 6], 2)] for i in range(0, len(bit_pattern), 6]
  • 결과를 하나의 String으로 join한다
    • ''.join([table[int(bit_pattern[i:i + 6], 2)] for i in range(0, len(bit_pattern), 6])

최종 코드

text = "Life itself is a quotation."

table = {i: s for i, s in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')}

bit_pattern = ''.join([bin(ord(s)[2:].zfill(8) for s in text])

base64 = ''.join([table[int(bit_pattern[i:i + 6], 2)] for i in range(0, len(bit_pattern), 6])

# base64 : TGlmZSBpdHNlbGYgaXMgYSBxdW90YXRpb24u

Decoding(Base64 to Text)

Hash Table 생성

table = {s: i for i, s in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')}

1. Base64 ( str ) -> Base64 code ( List[int] )

  • Base64 String을 Hash table을 사용해 Base64 code로 변환한다
    • [table[s] for s in base64]

2. Base64 code ( List[int] ) -> binary ( List[str] )

  • Base64 code를 binary로 변환한다
    • [bin(table[s]) for s in base64]

3. binary ( List[str] ) -> bit pattern ( str )

  • binary를 연결해서 bit pattern으로 만들기 위해 bin 한 결과의 앞부분을 정리한다
    • [bin(table[s])[2:] for s in base64]
  • ascii code로 변환하기 위해 6bit 크기의 chunk로 만든다
    • [bin(table[s])[2:].zfill(6) for s in base64]
  • 변환된 결과를 하나의 String으로 join 한다
  • ''.join([bin(table[s])[2:].zfill(6) for s in base64])

중간저장

bit_pattern = ''.join([bin(table[s])[2:].zfill(6) for s in base64])

4. bit pattern ( str ) -> ascii code ( List[int] )

  • bit patterb을 ascii 코드로 변환하기 위해 8bit 크기의 chunk로 순회한다
    • [bit_pattern[i:i + 8] for i in range(0, len(bit_pattern), 8)]
  • chunk를 int로 변환한다
    • [int(bit_pattern[i:i + 8], 2) for i in range(0, len(bit_pattern), 8)]

5. ascii code ( List[int] ) -> Text ( str )

  • chr를 사용해 ascii code를 ascii 문자열로 변환한다
    • [chr(int(bit_pattern[i:i + 8], 2)) for i in range(0, len(bit_pattern), 8)]
  • 결과를 하나의 String으로 join한다
    • ''.join([chr(int(bit_pattern[i:i + 8], 2)) for i in range(0, len(bit_pattern), 8)])

최종 코드

base64 = 'TGlmZSBpdHNlbGYgaXMgYSBxdW90YXRpb24u'

table = {s: i for i, s in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')}

bit_pattern = ''.join([bin(table[s])[2:].zfill(6) for s in base64])

text = ''.join([chr(int(bit_pattern[i:i + 8], 2)) for i in range(0, len(bit_pattern), 8)])

# text : Life itself is a quotation.

리팩토링

def conv(text, bin_func, str_func, before_chunk, after_chunk):
    b = ''.join(bin(bin_func(s))[2:].zfill(before_chunk) for s in text)
    return ''.join([str_func(int(b[i:i + after_chunk], 2)) for i in range(0, len(b), after_chunk)])


def encode(text: str):
    table = {i: s for i, s in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')}
    return conv(
        text=text,
        bin_func=ord,
        str_func=lambda x: table[x],
        before_chunk=8,
        after_chunk=6
    )


def decode(text: str):
    table = {s: i for i, s in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')}
    return conv(
        text=text,
        bin_func=lambda x: table[x],
        str_func=chr,
        before_chunk=6,
        after_chunk=8
    )
profile
하루를 나답게

0개의 댓글