블록체인관련 코드를 들여다보다가 바이트, 인코딩에 대해 좀 정리를 할 필요성을 느껴서 적게 되었다.
좀 어수선하지만 .. 관련 정보들이어서 묶어서 정리했다.
인코딩 정리:
- 세계 언어를 코드로 표기(유니코드) -> 이 코드를 컴퓨터가 이해할 수 있는 숫자로 변환(인코딩)
- 인코딩 종류는 ASCII, UTF-8 등 다양.
유니코드(Unicode)
세계 언어를 모두 표시할 수 있는 표준코드. 유니코드는 글자와 코드가 1:1매핑되어 있는 ‘코드표' (코드표)
Ref:
- https://jeongdowon.medium.com/unicode%EC%99%80-utf-8-%EA%B0%84%EB%8B%A8%ED%9E%88-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-b6aa3f7edf96
인코딩 - ASCII
- 유니코드를 컴퓨터가 이해할 수 있는 숫자로 변환한 코드.
- 아스키 코드에서는 7비트 부호로 128개의 숫자에 알파벳, 숫자, 특수문자, 제어문자가 할당
인코딩 - UTF-8
- 유니코드를 컴퓨터가 이해할 수 있는 숫자로 변환한 코드. 유니코드 -> 숫자로 변환
- UTF-8 유니코드 문서에 한글 등이 전혀 없고 영문과 숫자로 이루어져 있다면 아스키코드와 동일
유니코드를 통해 코드표가 정의되었다. 남은 것은 그 ‘코드'가 컴퓨터에 어떻게 저장되어야 하는 것이다. 다른 말로 인코딩(encoding)이라고 하는데, 컴퓨터가 이해할 수 있는 형태로 바꿔주는 것이다.
...
UTF-8은 가변 인코딩방식이다. 쉬운 말로 하면 글자마다 byte 길이가 다르다는 것이다. ‘a’는 1 byte이고 ‘가'는 3 byte이다.
...
가변을 구분하기 위해 첫 바이트에 표식을 넣었는데 2 byte는 110으로 시작하고 3바이트는 1110으로 시작한다. 나머지 바이트는 10으로 시작한다.
Ref:
- https://jeongdowon.medium.com/unicode%EC%99%80-utf-8-%EA%B0%84%EB%8B%A8%ED%9E%88-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-b6aa3f7edf96
- https://halfmoon9.tistory.com/61
Binary file (바이너리 파일)
- 컴퓨터 파일로 컴퓨터 저장과 처리 목적을 위해 이진형식으로 인코딩된 데이터를 포함
- 텍스트파일은 바이너리 파일의 부분집합
- 이미지 파일은 바이너리 파일
Ref:
- https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%ED%8C%8C%EC%9D%BC
- https://frhyme.github.io/python/binary_data/
byte: 1바이트 = 8비트 로 1~255(0x00 ~ 0xFF)까지 정수를 사용
파이썬에서 바이트관련 클래스:
- bytes: 바이트 단위의 값을 연속적으로 저장하는 시퀀스 자료형. element 변경 불가능
- bytearray: bytes와 마찬가지지이지만 element 변경 가능
변환
1. 문자열 -> 바이트 변환:
- 문자열의 기본 인코딩: UTF-8
- 문자열을 바이트객체로 만들면 각 문자를 ASCII 코드로 저장함. 보통 문자열을 UTF-8 -> ASCII 로 처리하고자 할 때 바이트 객체를 사용
- Ref: https://dojang.io/mod/page/view.php?id=2462
# String -> Bytes # Default encoding: utf-8 'hello'.encode() # == 'hello'.encode('utf-8') # output: # b'hello' # Bytes -> String b'hello'.decode() # output: # hello # Create a bytes instance with the specific encoding # 문자열.encode('인코딩') x = '안녕'.encode('euc-kr') # b'\xbe\xc8\xb3\xe7' x.decode('euc-kr') # '안녕' x = '안녕'.encode('utf-8') # b'\xec\x95\x88\xeb\x85\x95' x.decode('utf-8') # '안녕' bytes('안녕', encoding='euc-kr') # b'\xbe\xc8\xb3\xe7' bytearray('안녕', encoding='cp949') # bytearray(b'\xbe\xc8\xb3\xe7')
2. 16진수 -> ASCII:
- 항상 바이트로 변환을 거친다.
- Ref : https://www.delftstack.com/ko/howto/python/hex-to-ascii-python/
# 68656c6c6f -> 바이트로 변환 -> hello # Method 1: string = "68656c6c6f" byte_array = bytearray.fromhex(string) byte_array.decode() # Method 2: import codecs string = "68656c6c6f" binary_str = codecs.decode(string, "hex") print(str(binary_str,'utf-8'))
3. 문자열 -> 16진수:
- 항상 바이트로 변환을 거친다.
- Ref : https://www.delftstack.com/ko/howto/python/python-convert-hex-to-byte/
# 문자열 -> 바이트 -> 16진수 str_val = 'A quick brown fox'.encode('utf-8') hex_val = binascii.hexlify(str_val).decode('utf-8') # 16진수를 문자열화 print(hex_val) # 4120717569636b2062726f776e20666f78 # 16진수 -> 바이트 # Method 1 ---------- hex_val = '4120717569636b2062726f776e20666f78' print(bytes.fromhex(hex_val)) # Byte value: b'A quick brown fox' # Method 2 ---------- import binascii from binascii import unhexlify str_val = 'Μια γρήγορη καφέ αλεπού'.encode('utf-8') #A quick brown fox in Greek translation hex_val = binascii.hexlify(str_val).decode('utf-8') # 16진수 print('String value: ', str_val.decode('utf-8')) print('Hexadecimal: ', hex_val) # 16진수 print('Byte value: ', unhexlify(hex_val)) # output # String value: Μια γρήγορη καφέ αλεπού # Hexadecimal: ce9cceb9ceb120ceb3cf81ceaeceb3cebfcf81ceb720cebaceb1cf86cead20ceb1cebbceb5cf80cebfcf8d # Byte value: b'\xce\x9c\xce\xb9\xce\xb1 \xce\xb3\xcf\x81\xce\xae\xce\xb3\xce\xbf\xcf\x81\xce\xb7 \xce\xba\xce\xb1\xcf\x86\xce\xad \xce\xb1\xce\xbb\xce\xb5\xcf\x80\xce\xbf\xcf\x8d'
4. 문자의 ASCII값 가져오기
- ord()함수는 문자를 입력으로 취하고 문자의 유니코드에 해당하는 십진수 값을 정수로 리턴
- Ref: https://www.delftstack.com/ko/howto/python/python-char-to-ascii/
print(ord('a')) # 97 print(ord('A')) # 65 print(ord(',')) # 44