Git없이 파일에 Git SHA1을 할당하는 방법은 무엇입니까?
Git이 파일에 SHA1 해시를 할당 할 때이 SHA1은 내용에 따라 파일에 고유합니다.
결과적으로 파일이 한 저장소에서 다른 저장소로 이동하면 파일의 SHA1은 내용이 변경되지 않은 것과 동일하게 유지됩니다.
Git은 SHA1 다이제스트를 어떻게 계산합니까? 압축되지 않은 전체 파일 내용에서 수행됩니까?
SHA1을 Git 외부에 할당하는 것을 모방하고 싶습니다.
다음은 Git이 파일 (또는 Git 용어로 "블롭")에 대한 SHA1을 계산하는 방법입니다.
sha1("blob " + filesize + "\0" + data)
따라서 Git을 설치하지 않고도 쉽게 직접 계산할 수 있습니다. "\ 0"은 2 바이트 문자열이 아닌 NULL 바이트입니다.
예를 들어, 빈 파일의 해시 :
sha1("blob 0\0") = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
$ touch empty
$ git hash-object empty
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
다른 예시:
sha1("blob 7\0foobar\n") = "323fae03f4606ea9991df8befbb2fca795e648fa"
$ echo "foobar" > foo.txt
$ git hash-object foo.txt
323fae03f4606ea9991df8befbb2fca795e648fa
다음은 Python 구현입니다.
from hashlib import sha1
def githash(data):
s = sha1()
s.update("blob %u\0" % len(data))
s.update(data)
return s.hexdigest()
작은 케이크 : 쉘
echo -en "blob ${#CONTENTS}\0$CONTENTS" | sha1sum
git이 설치되어 있지 않은 경우 bash 쉘 함수를 사용하여 쉽게 계산할 수 있습니다.
git_id () { printf 'blob %s\0' "$(ls -l "$1" | awk '{print $5;}')" | cat - "$1" | sha1sum | awk '{print $1}'; }
git-hash-object 의 매뉴얼 페이지를 살펴보십시오 . 특정 파일의 git 해시를 계산하는 데 사용할 수 있습니다. 내가 생각하는 그 자식 피드 더 해시 알고리즘으로 파일의 내용 만 이상, 그러나 나는 확실히 알고하지 않으며,이 여분의 데이터에 공급 않는 경우에, 나는 그것이 무엇인지 알지 못한다.
/// Calculates the SHA1 for a given string
let calcSHA1 (text:string) =
text
|> System.Text.Encoding.ASCII.GetBytes
|> (new System.Security.Cryptography.SHA1CryptoServiceProvider()).ComputeHash
|> Array.fold (fun acc e ->
let t = System.Convert.ToString(e, 16)
if t.Length = 1 then acc + "0" + t else acc + t)
""
/// Calculates the SHA1 like git
let calcGitSHA1 (text:string) =
let s = text.Replace("\r\n","\n")
sprintf "blob %d%c%s" (s.Length) (char 0) s
|> calcSHA1
이것은 F #의 솔루션입니다.
완전한 Python3 구현 :
import os
from hashlib import sha1
def hashfile(filepath):
filesize_bytes = os.path.getsize(filepath)
s = sha1()
s.update(b"blob %u\0" % filesize_bytes)
with open(filepath, 'rb') as f:
s.update(f.read())
return s.hexdigest()
펄에서 :
#!/usr/bin/env perl
use Digest::SHA1;
my $content = do { local $/ = undef; <> };
print Digest::SHA1->new->add('blob '.length($content)."\0".$content)->hexdigest(), "\n";
쉘 명령으로 :
perl -MDigest::SHA1 -E '$/=undef;$_=<>;say Digest::SHA1->new->add("blob ".length()."\0".$_)->hexdigest' < file
그리고 Perl에서 ( http://search.cpan.org/dist/Git-PurePerl/의 Git :: PurePerl 참조 )
use strict;
use warnings;
use Digest::SHA1;
my @input = <>;
my $content = join("", @input);
my $git_blob = 'blob' . ' ' . length($content) . "\0" . $content;
my $sha1 = Digest::SHA1->new();
$sha1->add($git_blob);
print $sha1->hexdigest();
Ruby를 사용하면 다음과 같은 작업을 수행 할 수 있습니다.
require 'digest/sha1'
def git_hash(file)
data = File.read(file)
size = data.bytesize.to_s
Digest::SHA1.hexdigest('blob ' + size + "\0" + data)
end
다음과 동일한 출력을 생성하는 작은 Bash 스크립트 git hash-object
:
#!/bin/sh
(
echo -en 'blob '"$(stat -c%s "$1")"'\0';
cat "$1"
) | sha1sum | cut -d\ -f 1
자바 스크립트에서
const crypto = require('crypto')
const bytes = require('utf8-bytes')
function sha1(data) {
const shasum = crypto.createHash('sha1')
shasum.update(data)
return shasum.digest('hex')
}
function shaGit(data) {
const total_bytes = bytes(data).length
return sha1(`blob ${total_bytes}\0${data}`)
}
It is interesting to note that obviously Git adds a newline character to the end of the data before it will be hashed. A file containing nothing than "Hello World!" gets a blob hash of 980a0d5..., which the same as this one:
$ php -r 'echo sha1("blob 13" . chr(0) . "Hello World!\n") , PHP_EOL;'
참고URL : https://stackoverflow.com/questions/552659/how-to-assign-a-git-sha1s-to-a-file-without-git
'Programing' 카테고리의 다른 글
jQuery : 텍스트 상자 내에서 Tab 키 누르기를 캡처하는 방법 (0) | 2020.06.22 |
---|---|
py2exe-단일 실행 파일 생성 (0) | 2020.06.22 |
엔터티 프레임 워크 .Remove () 대 .DeleteObject () (0) | 2020.06.22 |
Find () 및 Where (). FirstOrDefault () (0) | 2020.06.22 |
RVM과 rbenv는 실제로 어떻게 작동합니까? (0) | 2020.06.22 |