Comando md5sum binário e modo de texto

Comando md5sum binário e modo de texto

O comando GNU md5sumpossui dois modos:bináriomodo etextomodo. Acho que a diferença está apenas em como os caracteres de nova linha são tratados. Estou certo?

No GNU/Linux, os dois modos sempre produzem o mesmo resultado, então o único uso das opções -be -té indicar o sinalizador ( *ou ) usado antes do nome do arquivo?

Em que circunstâncias os modos podem produzir resultados diferentes? Em sistemas Windows/MacOS? (Versões disponíveis para essas plataformas?)

Responder1

No GNU/Linux, os dois modos sempre produzem o mesmo resultado

Sim, explicitamente. De man md5sum:

Observação:Não há diferença entre a opção de modo binário e de texto no sistema [sic] GNU.

Isto vem da md5sumimplementação que acompanha o GNU coreutils 8.21; Percebo que uma versão mais antiga (8.12) não possui esse aviso, mas presumo que o mesmo seria verdade de qualquer maneira.

Embora o AFAICT md5sumnão seja oficialmente padronizado (por exemplo, pelo POSIX), ele está disponível em várias plataformas em diversas implementações e há obviamente algum esforço para torná-los compatíveis entre si para facilitar o uso em vários sistemas.

Em relação a isso, oPadrão ISO/ANSI Cinclui funções de fluxo de alto nível para acessar arquivos. Como parte do padrão, eles estão disponíveis em qualquer sistema operacional que implemente ISO C por meio de uma biblioteca compartilhada ou de um compilador. Como praticamente todos os sistemas operacionais têm isso disponível (e são geralmente escritos em C), é uma espécie de linguagem universal usada para implementar software potencialmente muito portátil.

Considerando o que ele faz, seria totalmente viável escrever um md5sumprograma que compilasse e funcionasse em qualquer sistema operacional. Não estou afirmando que isso seja verdade para a versão GNU coreutils, mas uma das funções de fluxo de arquivos de alto nível mencionadas anteriormente é fopen(), que é obrigatória pela ISO C para incluir uma bopção usada na abertura de um arquivo para indicar que ele está sendo aberto "como binário arquivo". O que isso pode significar ou exigir do sistemanão éestipulado pela norma, basta que exista para que possa ser utilizado em sistemas onde possa haver algum (qualquer) razão para isso.

Não existe esse motivo em sistemas operacionais estilo Linux/POSIX/*nix, então a opção não faz nada. Da especificação POSIX (um superconjunto de ISO C) parafopen():

O caracter 'b' não terá efeito, mas é permitido para conformidade com o padrão ISO C.

Portanto, uma implementação completamente portátil md5sumpode usar as funções de fluxo de arquivos de alto nível ISO, uma vez que não há outros métodos para acessar arquivos em ISO C (a maioria das plataformas, incluindo as de reclamação POSIX, também têm seus próprios métodos de nível inferior, mas usá-los seria não ser portável porque não estão em ISO C), e também deve implementar os sinalizadores -be -tpara adicionar ou não a bopção fopen()ao ler o arquivo. Em sistemas onde isso não faz sentido, não fará nenhuma diferença.

Novamente, não estou dizendo que o md5sum do GNU foi escrito de uma forma completamente portátil ou derivado de uma que é, mas obviamente ele está tentando estar em conformidade, em sua operabilidade, com uma que é. Observe que ter um sinalizador que não faz nada não é o mesmo que não ter o sinalizador - no primeiro caso, é especificado que está tudo bem, mas não faz nada, enquanto no último caso usá-lo pode ser um erro ou levar acomportamento indefinido.

Responder2

Como outros já afirmaram, nos sistemas GNU e no Windows moderno, estas opções não têm qualquer efeito.

Observando o código-fonte, quando md5sumusado com um arquivo, as opções de texto/binárias determinam se o modeparâmetro usado no fopen(const char *pathname, const char *mode)será "r"ou "rb". Em todos os sistemas em conformidade com POSIX, o bé simplesmente ignorado e não tem efeito.

Quando md5sumestá lendo a entrada padrão coreutilso padrão será o modo de textose e somente se todas as afirmações a seguir forem verdadeiras:

  • a macro de tempo de compilação O_BINARYé definida (ou seja, há uma diferença entre os modos texto e binário),
  • a entrada vem de um terminal
  • e o modo não é substituído por uma opção de linha de comando.

Caso contrário, o modo binário será assumido (a menos que seja substituído pela opção de linha de comando) e, se O_BINARYfor definido, xset_binary_mode()será chamado para entrada padrão.

xset_binary_mode()éum wrapper definido em xbinary-io.hof gnulib.Se O_BINARYfor indefinido, será uma função fictícia que será otimizada por qualquer bom compilador C - então, novamente, texto versus binário acaba não tendo efeito, mesmo que a função seja chamada por algum motivo.

Mas quando O_BINARYfor definido, xset_binary_mode()será um wrapper para set_binary_mode(), declarado embinary-io.hdegnulib. A partir daqui, encontraremos as primeiras pistas sobre ambientes de programação para os quais o “modo binário” realmente faz diferença:

#if O_BINARY
# if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__
#  include <io.h> /* declares setmode() */
#  define __gl_setmode setmode
# else
#  define __gl_setmode _setmode
#  undef fileno
#  define fileno _fileno
# endif
#else
  /* On reasonable systems, binary I/O is the only choice.  */
  /* Use a function rather than a macro, to avoid gcc warnings
     "warning: statement with no effect".  */
BINARY_IO_INLINE int
__gl_setmode (int fd _GL_UNUSED, int mode _GL_UNUSED)
{
  return O_BINARY;
}
#endif

Aparentemente, __EMX__éEberhard Mattes eXtender, um ambiente de programação no modo de 32 bits para MS-DOS e OS/2. Da mesma forma, __DJGPP__refere-se aoSistema de desenvolvimento DJGPP de 32 bits para MS-DOS. E depois há tambémCygwin. Todos esses ambientes de programação dependem de setmode()declarações declaradas em <io.h>.

Para outros ambientes de programação que definem O_BINARY, _setmode()(conforme definido pelo respectivo ambiente de programação) será usado.

Um exemplo de sistemas operacionais onde o modo texto versus o modo binário pode ser importante seria o OpenVMS. Ele também conhece a maneira estilo Unix de armazenar texto simplesmente como um fluxo de caracteres. No mundo OpenVMS, isso é aparentemente conhecido como Stream_LFformato - e o fato de ter um nome específico deve ser uma dica de que énão é a única maneira possível de formatar arquivos de texto.

Para os curiosos:http://neilrieck.net/docs/openvms_notes_text_files.html

Resumindo, no OpenVMS, o non-stream simple textformato do arquivo contém zero ou mais registros (linhas) cujo tamanho máximo é definido nos metadados do arquivo (pode ser de até 32.767 bytes). Cada linha é prefixada por um valor de 16 bits que indica o número de bytes em cada linha. Não existe "caractere de fim de linha": uma linha termina quando o número especificado de bytes é lido. Se o número de bytes em uma linha for ímpar, um 0x00byte de preenchimento será adicionado para ter o início da próxima linha em um endereço alinhado por palavra. Este byte de preenchimento nunca é contado no comprimento da linha.

GNU Coreutils certamente foiportado para OpenVMS.

Responder3

Como complemento, acrescentaria informações que no Windows md5sumtambém não há diferença no cálculo no modo --textou --binary. Testado em md5sum(GNU coreutils) 8.31 para Windows.

c:\temp\file-fingerprint-test\work-copy1\file-fingerprint-eol (master -> origin)
2021-05-30 - 7:35:52 PM
λ xxd unix-eol.txt
00000000: 7468 6973 2066 696c 6520 6861 7320 756e  this file has un
00000010: 6978 206c 696e 6520 656e 6469 6e67 730a  ix line endings.
00000020: 7468 6973 206d 6561 6e20 6974 2068 6173  this mean it has
00000030: 206f 6e6c 7920 4c46 0a                    only LF.

c:\temp\file-fingerprint-test\work-copy1\file-fingerprint-eol (master -> origin)
2021-05-30 - 7:36:08 PM
λ xxd win-eol.txt
00000000: 7468 6973 2066 696c 6520 6861 7320 7769  this file has wi
00000010: 6e20 206c 696e 6520 656e 6469 6e67 730d  n  line endings.
00000020: 0a74 6869 7320 6d65 616e 2069 7420 6861  .this mean it ha
00000030: 7320 2020 4352 204c 460d 0a              s   CR LF..

c:\temp\file-fingerprint-test\work-copy1\file-fingerprint-eol (master -> origin)
2021-05-30 - 7:36:15 PM
λ md5sum.exe --text *.txt
c8a8c7bb97ab554cff96a76b2a8f89fa  unix-eol.txt
03b3b1458cddff2cf1c15819b1255af3  win-eol.txt

c:\temp\file-fingerprint-test\work-copy1\file-fingerprint-eol (master -> origin)
2021-05-30 - 7:36:46 PM
λ md5sum.exe --bin *.txt
c8a8c7bb97ab554cff96a76b2a8f89fa *unix-eol.txt
03b3b1458cddff2cf1c15819b1255af3 *win-eol.txt

c:\temp\file-fingerprint-test\work-copy1\file-fingerprint-eol (master -> origin)
2021-05-30 - 7:36:57 PM
λ md5sum.exe --version
md5sum (GNU coreutils) 8.31
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Ulrich Drepper, Scott Miller, and David Madore.

informação relacionada