참조 :
Deterministic
x = y => h(x) = h(y)
암호화 해시 함수(Cryptographic Hash Function)
해시 함수의 일종으로 해시 값으로부터 원래의 입력값과의 관계를 찾기 어려운 성질을 가지는 경우를 의미
역상 저항성(preimage resistance)
해시 값이 주어졌을 때, 그 해시 값을 생성하는 입력값을 알아내기가 불가능하다는 특성
→ 입력값 A에 의해 B가 출력되었다면, 출력된 B만 주어졌을 때 입력값인 A값을 찾는 것이 계산적으로 불가능하다
제 2 역상 저항성(second preimage resistance)
어떤 입력 값과 동일한 해시 값(결과 값)을 가지는 다른 입력 값을 찾을 수 없어야 한다는 특성
→ 입력값 A와 출력값 B가 모두 주어졌을 때, 똑같은 B를 반환하는 A2를 찾아내거나 만들어내는 것이 계산적으로 불가능함을 의미
충돌 저항성(collision resistance)
해시 값(결과 값)이 같은 입력 값 두개를 찾을 수 없다는 특성,
충돌저항성은 제 2 역상 저항성의 외부효과(부수효과, Side effect)이자 부분집합이다.
→ 똑같은 B라는 출력값이 나오는 X가 단일하지 않고, 중복이 되는 또다른 Xn을 발견하는 것이 계산적으로 어려운 성질을 의미
참조 :
Chaining(체이닝)
Open Addressing(개방 주소법)
Resizing(리사이징)
이미지 | 설명 |
---|---|
Storage : | |
Bucket : | |
Tuple : |
_size
: 저장된 key-value 쌍의 갯수_bucketNum
: 해시 테이블의 스토리지 배열의 길이 지정_storage
: LimitedArray(_bucketNum)을 사용해 배열 생성insert(key, value)
: key, value 저장, key값이 있다면 덮어씌운다.retrieve(key)
: 주어진 키에 해당하는 값을 반환, 없다면 undefined반환remove(key)
: 주어진 키에 해당하는 값을 삭제하고 값을 반환, 없다면 undefined 반환_resize(newBucketNum)
: 해시 테이블의 스토리지 배열을 newBucketNum으로 리사이징하는 함수// LimitedArray에 포함된 get, set 메소드(?)를 쓰지 않고 배열을 사용한 방식이다. // 외부 폴더에서 준비되어 있는 해시 함수 (hashFunction) 가져온다. // 외부 폴더에서 배열의 크기를 제한시키 위한 함수(LimitedArray)을 가져온다. // ↑ 자바스크립트의 배열은 크기가 제한되어 있지않은 동적 배열이다. class HashTable { constructor() { this._size = 0; this._bucketNum = 8; this._storage = LimitedArray(this._bucketNum); } insert(key, value) { const index = hashFunction(key, this._bucketNum); // 해시값을 만드는 해시 함수 // 만약 this._storage[index]값이 없다면 // this._storage[index] 에 [[key, value]]를 할당해준다 // this._size++; // 그 외에는 // false를 할당한 isKey변수(키가 인덱스에 있는지 확인 후 value 재할당 용도) 선언 // 포문으로 this._storage[index]의 tuple확인 // 만약 this._storage[index][i][0] 가 키랑 같으면 // this._storage[index][i][1]에 value를 재할당 // key가 있으니 isKey변수를 true로 재할당 // 만약 isKey변수가 false면 (key, value는 새로 들어온 값이므로) // this._storage[index]에 [key, value]를 푸시한다. // this._size++ // 만약 this._size가 this._bucketNum의 75% 보다 작으면 // this._bucketNum를 2배로 늘려 this._resize함수의 인자값으로 넘겨 호출한다. } retrieve(key) { const index = hashFunction(key, this._bucketNum); // const arrIdx = this._storage[index].findIndex(el => el.includes(key)); // ↑ this._storage[index]의 요소가 key를 포함하고 있다면 인덱스 값을, 없다면 -1을 저장하는 변수 선언 // 만약 arrIdx가 -1보다 크면 // return this._storage[index][arrIdx][1]; } remove(key) { // 중요!! remove메소드를 실행하면 지운 값을 반환하게 만들었다. → 반환하지 않아도 된다면 더 간단하게 풀 수 있다... // this._size--; // 만약 this._size가 this._bucketNum의 25% 보다 크면 // this._bucketNum를 절반으로 줄여 this._resize함수의 인자값으로 넘겨 호출한다. const index = hashFunction(key, this._bucketNum); // retrieve에서 선언했던 arrIdx 똑같이 만들어준다.(key가 포함된 tuple의 인덱스를 얻기 위해) // 만약 arrIdx가 -1보다 크면 // return this._storage[index].splice(arrIdx, 1); // 그 외에는(arrIdx가 -1인 상태 = this._storage에 key가 없다) // this._size++; // 만약 this._size가 this._bucketNum의 75% 보다 작으면 // this._bucketNum를 2배로 늘려 this._resize함수의 인자값으로 넘겨 호출한다. // return undefined; } _resize(newBucketNum) { // 모든 키값이 저장된 this._storage에 새로운 값을 재할당하기전에 새로운 변수에 할당해준다. // ↑ (원래 값을 this._storage의 크기를 변경 후 해싱하기 위해) // 초기화 해주는 작업을 한다. // this._size는 0으로 재할당 // this._bucketNum은 인자로 받아온 newBucketNum 재할당 // this._storage = LimitedArray(this._bucketNum); // 포 인으로 originStorage(객체형태)에서 index를 가져온다. // 만약 originStorage[index]가 배열이라면 → limitedArray에 get, set, each메소드가 있기 때문에 // 포 오브로 originStorage[index]에서 arrIdx(tuple이라고 생각하면된다) // this.insert(...arrIdx); } }