SHA1을 얻는 방법에 따라 결과가 달라집니다.

SHA1을 얻는 방법에 따라 결과가 달라집니다.

나는 SHA1(특히 Git)을 배우고 있으며 다른 방법을 사용하여 문자열의 SHA1을 계산하여 내 이해를 확인하고 싶었습니다. 동일한 SHA1 해시를 기대했지만 대신 4가지 방법 중 3가지 방법에서 다른 결과를 얻었습니다.

>git hash-object --stdin <<< "Apple Pie"
23991897e13e47ed0adb91a0082c31c82fe0cbe5

.

>sha1sum <<< "blob 9\0Apple Pie"
332cd56150dc8b954c0b859bd4aa6092beafa00f  -

.

>printf 'blob 9\0Apple Pie' > foo.txt
>sha1sum foo.txt
9eed377bbdeb4aa5d14f8df9cd50fed042f41023  foo.txt

.

>openssl sha1 foo.txt
SHA1(foo.txt)= 9eed377bbdeb4aa5d14f8df9cd50fed042f41023

수락된 답변이 스택 오버플로 질문git hash-object"blob [파일 크기]/0"이라는 접두사가 붙은 지정된 콘텐츠에서 SHA1 해시가 실행됨을 나타냅니다 . 그래서 저는 Git이 아닌 메소드를 사용하여 테스트 중인 문자열의 접두사에 해당 텍스트를 명시적으로 추가합니다.

왜 이렇게 다른 결과가 나오는 걸까요? 나는 SHA1이 주어진 문자열에 대한 구체적이고 고유한 해시 값이고 SHA1의 다른 "유형"이 없다고 생각했습니다. 그렇지 않습니까?

답변1

차이점은 SHA1이 아니라 입력에서 발생합니다. 여기 문자열 구문은 다음과 같이 개행 문자를 추가합니다 od.

$ od -c <<< foo
0000000   f   o   o  \n

따라서 명령 git의 입력은 10자입니다 Apple Pie\n.

또한 여기서 문자열에 사용하는 큰따옴표는 \n또는 같은 백슬래시 이스케이프를 지원하지 \nnn않으므로 <<< "blob 9\0Apple Pie"리터럴 백슬래시와 0이 포함된 문자열을 제공합니다.

printf그러나 이는 \0NUL 바이트로 해석되며 후행 개행 문자를 추가하지 않으므로 개행 문자를 추가하고 길이를 수정한 후 예상되는 출력을 얻어야 합니다.

$ printf 'blob 10\0Apple Pie\n' | sha1sum
23991897e13e47ed0adb91a0082c31c82fe0cbe5  -

$''NUL 바이트 표시 를 지원하는 따옴표를 사용하여 여기서 문자열에 대해 동일한 작업을 수행할 수 있지만 \0NUL 바이트는 문자열을 종료하기 때문에 모든 쉘에서 작동하지 않을 수 있습니다. 예를 들어 Bash는 이를 처리할 수 없습니다 zsh. 다음을 수행할 수 있습니다.

$ zsh -c "sha1sum <<< $'blob 10\0Apple Pie'"
23991897e13e47ed0adb91a0082c31c82fe0cbe5  -

관련 정보