Как назначить Git SHA1 в файл без Git?

138
задан Ciro Santilli 新疆改造中心法轮功六四事件 17 May 2016 в 10:33
поделиться

6 ответов

Это - то, как Мерзавец вычисляет SHA1 для файла (или, в терминах Мерзавца, "блобе"):

sha1("blob " + filesize + "\0" + data)

, Таким образом, можно легко вычислить его сами, не устанавливая Мерзавца. Обратите внимание, что "\0" ПУСТОЙ байт, не две символьных строки.

, Например, хеш пустого файла:

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()
250
ответ дан Leif 17 May 2016 в 10:33
поделиться

Смотрите на страницу справочника для объект хеша мерзавца . Можно использовать его для вычислений хеша мерзавца какого-то конкретного файла. Я думаю , что мерзавец подает больше, чем просто содержание файла в хеш-алгоритм, но я не знаю наверняка, и если он действительно питается в дополнительных данных, я не знаю, каково это.

4
ответ дан Dale Hagglund 17 May 2016 в 10:33
поделиться

You can make a bash shell function to calculate it quite easily if you don't have git installed.

git_id () { printf 'blob %s\0' "$(ls -l "$1" | awk '{print $5;}')" | cat - "$1" | sha1sum | awk '{print $1}'; }
8
ответ дан 23 November 2019 в 23:27
поделиться
/// 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 #.

2
ответ дан 23 November 2019 в 23:27
поделиться

Небольшой подарок: в оболочке

echo -en "blob ${#CONTENTS}\0$CONTENTS" | sha1sum
17
ответ дан 23 November 2019 в 23:27
поделиться

И в Perl (см. Также Git :: PurePerl на http://search.cpan.org/dist/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();
1
ответ дан 23 November 2019 в 23:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: