문제1086--Hashcash

1086: Hashcash

시간제한 : 1.000 sec  메모리제한 : 128 MB

문제 설명

다음은 Hashcash 에 대한 설명이다.

비트코인에서 화폐를 발행하는 방식을 마이닝(mining)이라 부른다.  

비트코인의 화폐는 10분에 한 번씩 일정량이 생성되며 마이닝에 참여한 사용자 중 한 명에게 지급된다. 참여자들은 hashcash라는 문제를 풀어야 한다. hashcash는 특정한 조건을 가지는 해시값을 찾는 것이다.


예를 들어 가장 많이 사용하는 해시 알고리즘인 SHA-256으로 임의의 데이터를 해시한 값을 구하면 256비트(32바이트)의 값을 얻는다. 해시 함수는 단방향 함수라 데이터로부터 해시값을 구할 수는 있지만 해시값으로부터 데이터를 역산하는 것은 이론적으로 불가능하고, 해시값이 같은 임의의 데이터를 만들어 내는 것 역시 매우 어렵다. 특정한 해시값이 나오는 데이터를 찾으려면 2256개(256비트로 나올 수 있는 모든 경우의 수)의 데이터를 일일이 확인해야 한다. 현대의 컴퓨터로는 불가능한 작업이다.

hashcash 문제는 이 불가능한 역산 작업과 유사하다. 특정한 해시값이 나오는 데이터를 찾는 것은 너무 어려우니 특정한 범위의 해시값이 나오는 데이터를 찾도록 난이도를 낮춘 것이다. 다음 예를 보자.
SHA-256 ("hello world" + " 0") = 3cad76d283686392c9c1813baf25239a3f09b9e075d830984a9a93d62b93adb8
SHA-256 ("hello world" + " 1") = 063dbf1d36387944a5f0ace625b4d3ee36b2daefd8bdaee5ede723637efb1cf4
SHA-256 ("hello world" + " 2") = ed12932f3ef94c0792fbc55263968006e867e522cf9faa88274340a2671d4441
SHA-256 ("hello world" + " 3") = 4ffabbab4e763202462df1f59811944121588f0567f55bce581a0e99ebcf6606
SHA-256 ("hello world" + " 4") = 000e5e410dd915d190cce21d72a40bdbcc9db96d80de87d28896b56766f31b4e
SHA-256 ("hello world" + " 5") = f6471bb5cd1837f3ef4891903c40c5300c9f0fd8a902d5c3774628c44dab78ed
SHA-256 ("hello world" + " 6") = 6a9b5a89258b50744dfdf62e49ac6d869e8916e04ce57d9d1fc953daed9bfcd8  

"hello world"라는 문자열에 임의의 nonce 숫자(암호 시스템에서 사용하는 일회용 일련번호)를 덧붙여서 SHA-256으로 해시값을 구한 것이다. 해시값은 "SHA-256 hash calculator"와 같은 사이트에서도 쉽게 확인할 수있다. 위의 값 가운데 'hello world 1'과 'hello world 4'의 해시값의 시작 부분에는 숫자 0이 각각 1개와 3개가 있다. 0이 4개 이상인 해시값을 찾으려면 nonce 숫자를 조금 더 바꾸어 가면서 시도하면 될 것이다. 0의 개수가 하나씩 늘어날 때마다 확률적으로 16배씩 더 많은 nonce 숫자를 대입해 보아야 한다. 0의 개수가 5개인 해시값을 찾으려면 약 백만 개의 nonce 숫자를 대입해야 할 것이라 컴퓨터를 사용해도 쉽게 찾기 어렵다.


출처: http://d2.naver.com/helloworld/8237898

위의 설명을 읽고 입력 문자열에 대해서 다음과 같은 커스텀 해시값이 00000 으로 끝나도록 Nonce 값을 찾아 출력하시오.

각 언어별 해시 함수는 아래 구현을 참고하세요.

java

public static int CustomHash(String str) {

     long hash = 5381;

     for(int i = 0; i < str.length(); i++)

           hash = ((hash << 5) + hash) + str.charAt(i);

     return (int)(hash & 0x7FFFFFFF);

  }

c/c++

int CustomHash(const char *str) {

       unsigned long hash = 5381;

       int c;

       while (c = *str++)

           hash = ((hash << 5) + hash) + c;

       return hash & 0x7FFFFFFF;

}

python

def CustomHash(s):

   hash = 5381

   for x in s:

       hash = (( hash << 5) + hash) + ord(x)

   return (hash & 0x7FFFFFFF)

입력 문자열이 jessehouse 라고 했을 때 "jessehouse 7501" 의 커스텀 해시값은 2053230000 으로 뒷 4자리가 0000 으로 끝난다. 따라서 7501을 출력한다.
(jessehouse 와 7501 사이에 공백이 한 칸 있음에 유의하세요)

입력 설명

첫 줄에는 테스트 케이스의 개수 T(1<=T<=50)가 주어진다.

이어서 한 줄마다 입력 문자열 S(1 <= len(S) <= 1024) 가 주어진다.

출력 설명

각 테스트 케이스 별로 커스텀 해시값이 0000 으로 끝나도록 덧붙일 1이상의 Nonce 값을 찾아 출력한다.

입력 예시 Copy

1
jessehouse

출력 예시 Copy

7501

출처/분류