[cryptography] XOR이 해시를 결합하는 기본 방법 인 이유는 무엇입니까?

두 개의 해시가 H(A)있고 H(B)이를 결합하려고 한다고 가정하십시오 . 나는 두 개의 해시를 결합하는 좋은 방법이 XOR그들에게 있다는 것을 읽었습니다 XOR( H(A), H(B) ).

내가 찾은 가장 좋은 설명은 다음 해시 함수 지침 에 간략하게 설명되어 있습니다 .

대수 분포가 거의없는 두 숫자를 XOR하면 대수 분포가 다른 수는 여전히 발생하지만 두 값에 따라 달라집니다.



* 결합 할 두 숫자의 각 비트에서 두 비트가 같으면 0이, 그렇지 않으면 1이 출력됩니다. 즉, 조합의 50 %에서 1이 출력됩니다. 따라서 두 개의 입력 비트가 각각 대략 50 또는 50의 확률로 0 또는 1이면 출력 비트도 마찬가지입니다.

XOR이 OR 또는 AND 등이 아닌 해시 함수를 결합하기위한 기본 연산이어야하는 이유에 대한 직관 및 / 또는 수학을 설명 할 수 있습니까?



답변

균일하게 랜덤 한 (1 비트) 입력을 가정하면 AND 함수 출력 확률 분포는 75 % 0및 25 % 1입니다. 반대로, OR은 25 % 0및 75 % 1입니다.

XOR 함수는 50 % 0및 50 % 1이므로 균일 한 확률 분포를 결합하는 데 좋습니다.

이것은 진리표를 작성하여 볼 수 있습니다.

 a | b | a AND b
---+---+--------
 0 | 0 |    0
 0 | 1 |    0
 1 | 0 |    0
 1 | 1 |    1

 a | b | a OR b
---+---+--------
 0 | 0 |    0
 0 | 1 |    1
 1 | 0 |    1
 1 | 1 |    1

 a | b | a XOR b
---+---+--------
 0 | 0 |    0
 0 | 1 |    1
 1 | 0 |    1
 1 | 1 |    0

운동 :이 1 비트 입력 얼마나 많은 논리적 기능 ab이 균일 한 출력 분포를 가지고? XOR이 귀하의 질문에 명시된 목적에 가장 적합한 이유는 무엇입니까?


답변

xor해싱 할 때 사용할 위험한 기본 함수입니다. andand 보다 낫지 만 or많은 것을 말하지 않습니다.

xor대칭이므로 요소의 순서가 손실됩니다. 그래서 "bad"의지 해시와 같은 결합 "dab".

xor 쌍으로 동일한 값을 0에 매핑하므로 “공통”값을 0에 매핑하지 않아야합니다.

따라서 (a,a)0에 매핑되고 0에 (b,b)매핑됩니다. 이러한 쌍은 거의 임의성이 암시하는 것보다 거의 항상 흔하기 때문에 0보다 훨씬 많은 충돌이 발생합니다.

이 두 가지 문제 xor로 인해 표면에서 절반 정도 괜찮은 해시 결합기가 만들어졌지만 추가 검사 후에는 그렇지 않습니다.

최신 하드웨어에서는 일반적으로 거의 빠른 속도로 추가 xor합니다 (아마도 더 많은 전력을 사용하여이를 끌 수 있습니다). 덧셈의 ​​진리표는 xor문제의 비트 와 유사 하지만 두 값이 모두 1 일 때 다음 비트로 비트를 보냅니다. 이는 정보가 덜 지워짐을 의미합니다.

따라서 if hash(a) + hash(b)보다 결과가 0 대신에 더 낫습니다 .hash(a) xor hash(b)a==bhash(a)<<1

이것은 대칭으로 유지됩니다. 그래서 "bad""dab"같은 결과를 얻는 것은 문제가 남아있다. 적당한 비용으로이 대칭을 깨뜨릴 수 있습니다 :

hash(a)<<1 + hash(a) + hash(b)

일명 hash(a)*3 + hash(b). ( hash(a)시프트 솔루션을 사용하는 경우 한 번 계산 하고 저장하는 것이 좋습니다). 부호없는 정수에 대한 맵 은 일부 에 대해 수학적인 모듈러스이고 , 홀수 상수는 비교적 소수이기 때문에 대신에 홀수 상수 대신 3k-비트”부호없는 정수를 자신에 매핑 합니다 .2^kk2^k

더 멋진 버전의 경우 다음을 boost::hash_combine효과적으로 검사 할 수 있습니다 .

size_t hash_combine( size_t lhs, size_t rhs ) {
  lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
  return lhs;
}

여기에 우리 seed는 상수 (기본적으로 임의 0의 s와 1s입니다-특히 32 비트 고정 소수점 분수와 같은 황금 비율의 역수)를 가진 일부 버전과 xor를 추가합니다. 이 휴식은 대칭 및 수신 해시 값이 있다면 소개합니다은 일부는 “노이즈”, 즉 0으로 모든 구성 요소 해시를 상상 (가난한 – 위의 손잡이는 잘의 얼룩을 생성 1하고 0. 각 결합 후이야 내 순진 3*hash(a)+hash(b)단순히 출력 0의를 그 경우).

(C / C ++에 익숙하지 않은 사용자의 경우 a size_t는 메모리에있는 오브젝트의 크기를 설명하기에 충분히 큰 부호없는 정수 값입니다. 64 비트 시스템에서는 일반적으로 64 비트 부호없는 정수입니다. 32 비트 시스템에서 , 32 비트 부호없는 정수)


답변

편리한 비트 믹싱 속성에도 불구하고 XOR은 정류 성으로 인해 해시를 결합하는 좋은 방법 이 아닙니다 . {1, 2,…, 10}의 순열을 10- 튜플의 해시 테이블에 저장하면 어떻게 될지 고려하십시오.

m 이 큰 홀수 m * H(A) + H(B)인 곳 이 훨씬 더 나은 선택입니다 .

크레딧 : 위의 결합기는 Bob Jenkins의 팁이었습니다.


답변

Xor는 해시를 결합하는 “기본”방법 일 수 있지만 Greg Hewgill의 답변은 그 함정이있는 이유를 보여줍니다. 두 개의 동일한 해시 값의 xor는 0입니다. 실제로는 예상했던 것보다 동일한 해시가 더 일반적입니다. 그런 경우가 많지 않은 코너 사례에서 결과 결합 해시는 항상 동일하다는 것을 알 수 있습니다. 해시 충돌은 예상보다 훨씬 더 자주 발생합니다.

고안된 예에서는 관리하는 다른 웹 사이트의 사용자의 해시 비밀번호를 결합 할 수 있습니다. 불행히도 많은 사용자가 자신의 암호를 재사용하고 결과 해시의 놀라운 비율은 0입니다!


답변

이 페이지를 찾는 다른 사람들에게 명시 적으로 지적하고 싶은 것이 있습니다. AND 및 OR BlueRaja와 같은 출력 제한-Danny Pflughoe가 지적하려고하지만 더 잘 정의 할 수 있습니다.

먼저 Min ()과 Max ()라는 두 가지 간단한 함수를 정의하고 싶습니다.

Min (A, B)는 A와 B 사이에서 작은 값을 반환합니다 (예 : Min (1, 5)는 1을 반환 함).

Max (A, B)는 A와 B 사이에서 더 큰 값을 반환합니다 (예 : Max (1, 5)는 5를 반환 함).

당신이 주어진 경우 : C = A AND B

그런 다음 C <= Min(A, B)A 또는 B의 0 비트로 AND를 1로 만들 수있는 것이 없기 때문에 이것을 알 수 있습니다. 따라서 모든 0 비트는 0 비트를 유지하며 모든 1 비트는 0 비트가 될 가능성이 있습니다 (따라서 더 작은 값).

와: C = A OR B

반대의 경우도 마찬가지입니다.이를 C >= Max(A, B)통해 AND 함수에 대한 결과를 볼 수 있습니다. 이미 1 인 비트는 0으로 OR 될 수 없으므로 1로 유지되지만 모든 0 비트는 1이 될 가능성이 있으므로 더 큰 숫자가됩니다.

이는 입력 상태가 출력에 제한을 적용 함을 의미합니다. AND를 90으로 설정하면 다른 값이 무엇이든 출력이 90 이하임을 알 수 있습니다.

XOR의 경우 입력을 기반으로 함축 된 제한이 없습니다. 255의 바이트를 XOR하면 역수보다 바이트를 얻을 수 있지만 그로부터 가능한 바이트를 출력 할 수있는 특별한 경우가 있습니다. 모든 비트는 다른 피연산자의 동일한 비트에 따라 상태를 변경할 수 있습니다.


답변

당신이 경우 XOR바이어스 입력을 임의의 입력, 출력은 랜덤입니다. AND또는에 대해서도 마찬가지입니다 OR. 예:

00101001 XOR 00000000 = 00101001
00101001 및 00000000 = 00000000
00101001 또는 11111111 = 11111111

마찬가지로 @Greg Hewgill이 경우에도 언급 모두 입력을 사용하여 랜덤 AND또는 OR바이어스 출력 될 것이다.

우리가 XOR더 복잡한 것을 사용하는 이유는 , XOR완벽하게 작동하고 엄청나게 빠르기 때문입니다.


답변

왼쪽 2 열을 덮고 입력 만 출력을 사용하여 무엇을 해결하려고 노력하십시오.

 a | b | a AND b
---+---+--------
 0 | 0 |    0
 0 | 1 |    0
 1 | 0 |    0
 1 | 1 |    1

1 비트를 보았을 때 두 입력이 모두 1이라는 것을 알아 내야했습니다.

이제 XOR에 대해 동일한 작업을 수행하십시오.

 a | b | a XOR b
---+---+--------
 0 | 0 |    0
 0 | 1 |    1
 1 | 0 |    1
 1 | 1 |    0

XOR은 입력에 대해 아무 것도주지 않습니다.