Swift 해시(hashable) - Swift

안녕하세요, 테디호프입니다.
오늘은 콜렉션 타입에 대해 공부하고 정리를 하려고하였는데,
중간 중간 NS접두사가 붙은 클래스, Generic 타입 그리고 Hash라는 용어가 자주 나와서 찾아봤습니다.

이런 용어들은 Swift나 애플 공식홈페이지에서 찾아보면 어떤 부분은 정말 교과서적으로 심플하게 설명이 나와있어서, 비전공자는 설명을 보고 '이 한줄이 의미하는게 도대체 뭐야?'라고 추가로 검색을 하게 됩니다. (... 뭔지 몰라서 다시 구글 검색을 하죠, 아.. 아니라구요?.. 네.. 엄.. )

인터넷은 참 좋은 것 같아요. 모르는 내용을 검색하면 대부분 찾을 수 있습니다.
다만 정보가 너무 방대하다보니 ... 같은 내용이지만 설명이 달라서 여러 블로그와 웹사이트를 찾아 보면서 개념을 정리하게됩니다. 그렇게 저도 여기저기 방문하면서 드디어! Swift에서 얘기하는 hash가 뭔지 감을 어느정도 잡게 되었습니다.
(혼자만의 생각일지도요...)

그래서 hashable? hash? hasher? 이런게 뭔데~ 를 정리해봅니다. 



Hash

(1) Hash가 뭔가요? - Hash의 개념 및 특징
(2) Hash는 왜 사용하죠? - 사용 예시
(3) Swift에서 Hash가 갖는 의미는? 




(1) Hash가 뭔가요?

해시라는 것은 생각보다 먼 곳에 있는 것이 아닌 프로그래밍 곳곳에 있습니다. 
일종의 데이터를 Integer나 String 형태로 생성하여 Index와 같은 것을 매기는 기법입니다. 
데이터는 Hash Function 혹은 Hasher를 통해서 생성되며 생성 값을 Hash value, Hash Code 혹은 심플하게 Hash라고 합니다. 

네? 무슨 말인지 모르시겠다구요(?) 저도 이 말만 듣고 몰랐죠. 자 아래 그림을 볼까요?


위 그림은 Hash Code를 만드는 일련의 과정을 보여주고 있습니다. 이를 Hashing Process라고 합니다. 
사과, 오렌지, 복숭아, 파인애플이라는 데이터들이 Hash Function을 통해서 숫자가 되어 Hash Value가 되었죠. 
Hash Value는 보기에 랜덤한 숫자로 보입니다. 이러한 Hash는 몇가지 특징이 있습니다.



Hash의 특징

1. Hashing Process는 반복 수행이 가능해야 한다. 만약 같은 데이터 값이라면 같은 Hash 값을 지녀야 합니다. 
만약 우리가 '사과'라는 데이터를 처리하면 언제나 839021이란 값으로 변환될 것입니다. 

2. Hash값은 유니크 해야합니다. 사과, 오렌지, 복숭아 그리고 파인애플은 모두 고유의 Hash Value를 지녔죠. 
만약 우리가 새로운 과일로 딸기를 추가할 경우 Hash Function은 542381이란 값을 줄 것입니다. 

3. Hash값은 랜덤해야합니다. 일반적으로 Hash값만 보고 원래의 데이터가 무엇인지 알 수 없는 조합으로 구성됩니다.

4. Hash값은 무조건 양의 정수일 필요가 없습니다. 간단한 예시를 들기 위해서 그림은 정수만 표현하였지만,
Hash Function에 따라서 Hash값은 음의 정수, 문자, 기호들로도 표현될 수 있습니다. 

5. 3번에 이어서 Hash 값의 역은 성립되지 않습니다. 
즉 데이터를 Hash값으로 표현은 할 수 있지만, Hash값을 통해 이 데이터가 무엇인지는 알 수 없어야 합니다. 일방통행이죠.





(2) Hash는 왜 사용하죠? 


[예시1: 인터넷 검색]


만약 여러분이 위와 같은 거래처의 목록을 가지고 있다고 해봅시다.
어느날 자동차를 사야하는데 주변 친구가 John's Mechanic이 서비스가 좋아! 여기서 사는게 어때? 라고 추천하였고 
인터넷에서 검색을 하게되겠죠.



* Hash를 사용하지 않을 경우?

여러분의 컴퓨터는 입력된 15개의 문자 John's Mechanic을 모든 표의 작성된 가게명과 비교하여 찾게됩니다. 그런데 만약에 수백 수만개의 데이터를 가진 표라면 검색에 걸리는 시간은 길어지겠죠.

여기서 Hash에서는 이런 검색 방식을 O(n) 으로 표기하며, 뜻하는 바는 데이터의 크기와 종류가 증가함에 따라 처리 시간도 선형적으로 증가하는 것을 나타냅니다. 


* Hash를 사용할 경우?

그런데 어느날 가게 목록을 관리하는 담당자가 Hash를 배워서 적용했습니다. 그리고 Hash Function을 통해 가게명마다 고유의 Hash값을 만들어 Index로 활용하게 되었죠. 

이제 다시 John's Mechanic으로 인터넷 검색을 수행할 경우 여러분의 컴퓨터는 이제 15개의 글자를 비교하지 않고 Index에 해당하는 003 값으로 가게를 찾게됩니다. 15글자를 비교하는 것과  3자리의 숫자를 비교하는 것은 상당한 차이이며 검색 시간이 단축될 것입니다.

이런 기법을 O(1)으로 표기하고 의미는 검색에 소요된 시간과 데이터 크기는 독립적이라는 것입니다.





[예시2: 인터넷 비밀번호]

만약 여러분이 인터넷에 비밀번호를 입력하고 이것이 단지 문자열로 표현될 경우 이는 보안이 취약하게 됩니다. 
비밀번호를 입력하고 호스트 서버에 입력되었는데, 서버 관리자가 자리를 비운 사이에 여러분의 암호 문자열이 그대로 노출된다면 복사하기도 쉽고 해킹 당할 수 있겠습니다. 

그런데 여러분의 암호가 Hash Function을 통해서 Hash 값을 통해 전달될 경우에 이러한 암호 노출에 대한 위험을 줄일 수 있습니다. 값을 봐도 이게 무엇을 의미하는지 쉽게 알 수 없기 때문이죠. 



위 그림을 보았을 때, 
암호가 newyear2020으로 입력되어 newyear2020으로 전달되어 보여지는 것과 대비하여 Hash Function을 통해 생성된 값은 382730918380으로 의미를 쉽게 알아차릴 수 없는 값으로 암호화됩니다.


이 밖에도 Hash는 다양한 곳에서 활용되고 있으며 블록체인 기술에도 활용되고 있다고 합니다.





(3) Swift에서 Hash가 갖는 의미는? 
 
앞서 알아본 Hash의 개념을 통해서 Swift에서는 Hashing Protocol을 통해 어떤 의미를 갖는지 알아봅시다.
여기서 Protocol이란 것은 어떤 서비스를 이용하기 위해서 준수해야하는 약속같은 것인데요, 
나중에 따로 더 공부하고 설명드릴 기회가 있어서 지금은 이정도 수준으로 넘어가겠습니다.
(저도 지금은 개념만 알고 있을뿐... 깊이있게 찾아보질 않았어요. 찾다가 또 삼천포로 빠질 것 같아서요 '')

애플 개발자 사이트에서 Hashable Protocol을 검색하면 아래와 같은 정의라고 합니다.  


 “A type that can be hashed into a Hasher to produce an integer hash value.”


어떤 하나의 타입이 Hasher를 통해 hash되어서 하나의 정수 hash값을 생성하는 것,
만들어진 Hash값은 Swift에서 64-bit 정수(Int) 크기의 값을 갖습니다. 
(크기가..18,446,744,073,709,551,615 정도된다고 하네요.)

자 이제 앞서 설명한 Hash의 개념을 알았으니 대충 맥락이 이해되시겠죠? 
그렇습니다. 고유한 값으로 검색이나 보안 등등에 손쉽고 빠르고 안전하게 활용하기 위해서 특정 데이터에 대한 별도의 값을 생성해준다는 것이죠. 다만 생성된 Hash값이 꼭 고유하지는 않고 데이터 또는 Hash Function에 따라 생성된 값이 겹치는 상황도 있다고 합니다. 이 경우에는 이를 보완하는 기법들도 있다고 하는데요...! 


...



이 후에 내용은 조금 심화적인 것이라 제가 조금 더 이해를 해야 정리할 수 있을 것 같습니다.
지금은 단지 이정도로 개념과 왜 사용하는지에 대해 알고만 있어도 도움이 많이 됩니다. 
아마 콜렉션 타입을 얘기하면서 Hashble에 대한 이야기가 나올텐데 여기서도 더 이야기 할 수 있을 것 같네요.


참고한 글: 


테디호프 드림

핑백

  • 테디호프의 이글루입니다. : Swift 콜렉션 타입 2021-05-07 16:03:57 #

    ... 아 있네요. ^^; 이 글에다가 같이 작성하면 양이 너무 많아 질 것 같아서 나중에 따로 정리를 해봐야겠습니다. 아래표를 보시다가 Hashable, NSClass 그리고 Generic가 무엇인지 모르겠다면밑줄친 부분을 누르면 해당 용어의 설명글로 이동하게 됩니다.&nbsp ... more

덧글

댓글 입력 영역