해싱은 수학적 알고리즘을 사용하여 데이터를 매핑하고 압축하는 기술입니다. 이 기술은 다양한 크기의 입력 데이터(예: 이미지)를 동일한 크기의 출력 데이터(예: 데이터 지문, 디지털 ID)로 변환합니다. 해시 함수는 임의의 입력 비트열에 대해 일정한 길이의 안전한 출력 비트열을 생성하며, 정보 보호 분야에서 활발히 활용됩니다.
해시는 문자열(string)을 기준으로 정보를 기록하고 관리할 때 주로 사용됩니다. 인덱스 기반의 단순 배열을 사용할 수 없는 경우, key:value의 매핑 구조에서 key가 문자열일 때 해시를 활용합니다. 예를 들어, 등록된 전화번호를 기준으로 '개인안심번호'를 생성하는 데 해시가 사용됩니다.
해시는 key:value 매핑 구조입니다.
대부분의 경우 key가 문자열입니다.
put/get/getOrDefault 메서드를 사용하여 데이터를 저장하고 값을 가져올 수 있습니다.
해싱 함수에 대해 간략하게 알아보았으니, 해싱 함수를 만들어 봅시다.
고정된 길이를 가져야하니, 문자열을 일정한 길이로 나누는 것이 좋을 것 같습니다.
def folding_hash(input_data, table_size, hash_length=8):
input_bytes = input_data.encode()
chunks = [input_bytes[i:i+4] for i in range(0, len(input_bytes), 4)]
hash_value = sum(map(lambda x: int.from_bytes(x, byteorder='little'), chunks))
hash_value = hash_value % table_size
return f"{hash_value:0{hash_length}d}"
보니까 이게 대부분의 해싱 함수 요구사항을 만족하지 못하는 것 같습니다.
실패!
제 아이디어는 아닌데 이렇게 ASCII 코드 값을 사용하고 2^32로 나머지 연산을 수행해서 길이가 고정되게끔 했습니다.
13은 제가 가장 좋아하는 소수 중에 하나라 넣었습니다.
def custom_hash_function(message):
hash_value = 0
for char in message:
hash_value = (hash_value * 13 + ord(char)) % (2**32)
return hash_value
가장 신경썼던 고정 크기 출력을 해결했습니다.
균일성을 만족합니다.
여전히 비가역성, 충돌 회피, 제2역상 저항성을 만족하지 못합니다.
일단 제2역상 저항성을 높이기 위해 비트 연산을 넣기로 했습니다.
AND와 OR, XOR 중에 고민하다가 XOR이 가장 이쁜 것 같아서 선택했습니다.
def custom_hash_function(message):
hash_value = 0
for char in message:
hash_value = (hash_value * 13) ^ (ord(char) << 1) ^ ord(char)
return hash_value
그래도 제2역상 저항성이 좀 나아진 것 같네요.
비가역성, 충돌 회피는 여전히 만족하지 못합니다.
그러니 이미 있는 SHA-256같은 해시 함수를 쓰는 것이 좋겠죠?
좋은 하루 되세요.