Eu estava usando o 7zip para calcular o hash de uma pasta (com subpastas), o que pode ser feito com duas opções, com ou sem inclusão dos nomes dos arquivos.
No entanto, na versão Linux do 7zip, o recurso hash não está implementado. Eu tentei diferentemétodospara duplicar o resultado, mas nenhum desses métodos daria o mesmo resultado no Linux e no Windows.
Exemplos de resultados:
" 7za.exe h -scrcsha1 myfolder
" no Windows dá:
SHA1 for data: D54D3168B16BFEE600C3A77E848A2A1C1DBCBC59
SHA1 for data and names: BCE55085200581AD1774CC25AE065DE7DE60077D
, enquanto no Linux eu tenho:
find . -type f -exec sha1sum "$PWD"/{} \; | sha1sum
ee44137f2462bdfea87ec824dab514f288ae3e6c -
ou
find . -type f | xargs sha1sum | sha1sum
8f971311a28bcdee36fab0ce87a892564622db40 -
Portanto não posso usar o resultado de uma plataforma em outra.
(Verifiquei se o resultado de um único arquivo é o mesmo para ambas as plataformas.)
Responder1
Simplesmente executar o seguinte comando não funcionará necessariamente:
find . -type f | xargs sha512sum | sha512sum
O problema que você pode enfrentar é que a ordem dos arquivos relatados find
é diferente de sistema para sistema ou mesmo de cópia de diretório para cópia.
Em vez disso, tente executar o seguinte:
find . -type f | sort | xargs sha512sum | sha512sum
Sinta-se à vontade para trocar por sha512sum
outro - por exemplo: md5sum
// dependendo de suas necessidades.sha1sum
sha256sum
Observe que isso pode ficar lento para árvores de diretórios grandes; nesse caso, você pode preferir um script mais complexo para percorrer a hierarquia.
Exemplo:
$ find . -type f | xargs sha512sum | sha512sum
097e56f6b751c1da15ce5b9dce853ffcc89e06e9cbe10a8dc0894dedb834d40dc4228c65e48bd53f136dd6a7700b0ab07e8e12e7100956db00b0d1b9ef0b9956 -
Isso inclui nomes de arquivos e conteúdo no hash final, mas não inclui metadados - horários de modificação, permissões, etc.
Observe que você pode usar esses utilitários no Windows usando "Subsistema Windows para Linux". Acabei de instalá-lo, o que foi uma experiência indolor e que também me fez perceber o problema com o find
pedido relatado por.
Observe também como os links simbólicos são tratados em sua árvore no Linux e no Windows.
Responder2
Infelizmente, parece impossível reproduzir o hash de uma pasta gerada pelo 7-zip.
Isso ocorre porque 7z usa a função FindNextFileW() para enumerar os diretórios (7z-1900src/CPP/Windows/FileFind.cpp, linha 198).
A ordem do valor de retorno da função não é garantida e pode depender do sistema de arquivos (de acordo comhttps://docs.microsoft.com/zh-cn/windows/win32/api/fileapi/nf-fileapi-findnextfilew).
Portanto, se você deseja implementar uma função de hash de diretório independente de plataforma, você deve usar uma função de classificação unificada.
Responder3
Como o Linux não pode duplicar a soma de verificação 7zip e eu não tenho nodeJS, instalei o "Windows Subsystem for Linux" para verificar uma cópia de pasta de um computador Windows para um Synology NAS. Instalar o WSL foi bastante fácil, basta seguiros documentos.
Para um comando que realmente gerou o mesmo hash no Windows e no Linux, referi-me principalmente aComo posso calcular uma soma de verificação MD5 de um diretório?, que explica como classificar os resultados de forma consistente entre Windows e Linux e também como NÃO ignorar diretórios vazios. A classificação consistente é realizada com LC_ALL=C
:
find . -type f -print0 | LC_ALL=C sort -z | xargs -r0 sha512sum | sha512sum
Mas isso não lida com diretórios vazios, então aqui está um comando mais completo copiado da outra resposta. Ele não é usado -print0
para reduzir a complexidade, mas o Windows não permite novas linhas e caracteres especiais em nomes de arquivos/pastas, então não é grande coisa.
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
Por último, o Synology cria arquivos/pastas extras para indexação, então também tive que ignorar os arquivos de índice com extensão -not -path
. Este foi meu comando final que gerou a mesma soma de verificação no WSL para minha pasta do Windows e no Synology SSH para a pasta copiada:
dir=.; (find "$dir" -type f -not -path '*@eaDir*' -exec sha512sum {} +; find "$dir" -type d -not -path '*@eaDir*') | LC_ALL=C sort | sha512sum