md5sum-Befehl im Binär- und Textmodus

md5sum-Befehl im Binär- und Textmodus

Der GNU- md5sumBefehl hat zwei Modi:binärModus undTextModus. Ich vermute, der Unterschied besteht nur darin, wie Zeilenumbruchzeichen behandelt werden? Habe ich Recht?

Unter GNU/Linux führen die zwei Modi immer zum gleichen Ergebnis, daher besteht die einzige Verwendung der Optionen -bund darin, das vor dem Dateinamen verwendete Flag ( oder ) -tanzugeben ?*

Unter welchen Umständen können die Modi unterschiedliche Ergebnisse liefern? Auf Windows-/MacOS-Systemen? (Versionen für diese Plattformen verfügbar?)

Antwort1

Unter GNU/Linux führen die beiden Modi immer zum selben Ergebnis

Ja, ausdrücklich. Von man md5sum:

Notiz:Es gibt keinen Unterschied zwischen der Binär- und der Textmodusoption im GNU-System.

Dies stammt aus der md5sumImplementierung, die mit GNU Coreutils 8.21 ausgeliefert wird. Mir ist aufgefallen, dass eine ältere Version (8.12) diesen Hinweis nicht enthält, aber ich gehe davon aus, dass dies auch hier der Fall ist.

Obwohl AFAICT md5sumnicht offiziell standardisiert ist (z. B. durch POSIX), ist es auf verschiedenen Plattformen in unterschiedlichen Implementierungen verfügbar und es werden offensichtlich Anstrengungen unternommen, diese miteinander kompatibel zu machen, um eine systemübergreifende Benutzerfreundlichkeit zu gewährleisten.

In diesem Zusammenhang ist dieISO/ANSI C-Standardenthält hochrangige Stream-Funktionen für den Zugriff auf Dateien. Als Teil des Standards sind diese auf jedem Betriebssystem verfügbar, das ISO C über eine gemeinsam genutzte Bibliothek oder einen Compiler implementiert. Da dies praktisch auf allen Betriebssystemen verfügbar ist (und selbst meist in C geschrieben ist), ist es eine Art universelle Sprache, mit der potenziell sehr portable Software implementiert werden kann.

Wenn man bedenkt, was es tut, wäre es durchaus möglich, ein zu schreiben, md5sumdas auf jedem Betriebssystem kompiliert und ausgeführt werden kann. Ich behaupte nicht, dass dies für die GNU-Coreutils-Version gilt, aber eine der oben erwähnten High-Level-Dateistreamfunktionen ist fopen(), die von ISO C vorgeschrieben wird, um einen Schalter einzuschließen, bder beim Öffnen einer Datei verwendet wird, um anzuzeigen, dass sie „als Binärdatei“ geöffnet wird. Was das für das System bedeuten oder erfordern kannist nichtdurch den Standard festgelegt, es muss nur vorhanden sein, damit es auf Systemen verwendet werden kann, auf denen es einige gibt (beliebig) Grund dafür.

Es gibt keinen solchen Grund für Linux/POSIX/*nix-artige Betriebssysteme, daher bewirkt der Schalter nichts. Aus der POSIX-Spezifikation (eine Obermenge von ISO C) fürfopen():

Das Zeichen „b“ hat keine Auswirkung, ist aber aus Konformitätsgründen zum ISO-C-Standard zulässig.

Eine vollständig portable md5sumImplementierung könnte also die ISO-High-Level-Dateistreamfunktionen verwenden, da es in ISO C keine anderen Methoden für den Zugriff auf Dateien gibt (die meisten Plattformen, einschließlich POSIX-kompatibler, haben auch ihre eigenen Low-Level-Methoden, aber deren Verwendung wäre nicht portierbar, da sie nicht in ISO C enthalten sind). Außerdem sollten die Flags und implementiert werden, -bum die Option beim Lesen der Datei -thinzuzufügen oder nicht hinzuzufügen . Auf Systemen, auf denen dies bedeutungslos ist, macht es keinen Unterschied.bfopen()

Ich sage nicht, dass GNUs md5sum so vollständig portabel geschrieben ist oder von einem solchen abgeleitet ist, aber es versucht offensichtlich, in seiner Funktionsfähigkeit mit einem solchen zu harmonieren. Beachten Sie, dass ein Flag, das nichts tut, nicht dasselbe ist wie das Fehlen des Flags – im ersten Fall ist es so spezifiziert, dass es in Ordnung ist, aber nichts tut, während es im zweiten Fall einen Fehler geben oder zuundefiniertes Verhalten.

Antwort2

Wie andere bereits erklärt haben, haben diese Optionen auf GNU-Systemen und modernen Windows-Systemen keinerlei Auswirkungen.

Betrachtet man den Quellcode, so md5sumbestimmen die Text-/Binäroptionen, ob modebei Verwendung mit einer Datei der verwendete Parameter oder fopen(const char *pathname, const char *mode)ist . Auf allen POSIX-konformen Systemen wird einfach ignoriert und hat keine Auswirkung."r""rb"b

Beim md5sumLesen wird die Standardeingabe coreutilsstandardmäßig in den Textmodus umgeschaltet.genau dann, wenn alle der folgenden Aussagen zutreffen:

  • das Makro zur Kompilierungszeit O_BINARYdefiniert ist (d. h. es gibt einen Unterschied zwischen Text- und Binärmodus),
  • Die Eingabe kommt von einem Terminal
  • und der Modus wird nicht durch eine Befehlszeilenoption überschrieben.

Andernfalls wird der Binärmodus angenommen (sofern er nicht durch eine Befehlszeilenoption überschrieben wird) und, sofern O_BINARYdefiniert, xset_binary_mode()für die Standardeingabe aufgerufen.

xset_binary_mode()Istein in definierter xbinary-io.hWrapper gnulib.Wenn O_BINARYes nicht definiert ist, handelt es sich um eine Dummy-Funktion, die von jedem guten C-Compiler durch Optimierung wegoptimiert wird. Daher hat Text vs. Binär wiederum am Ende keine Auswirkung, selbst wenn die Funktion aus irgendeinem Grund aufgerufen würde.

Aber wenn O_BINARYdefiniert ist, xset_binary_mode()wird es ein Wrapper für sein set_binary_mode(), deklariert inbinary-io.hvongnulib. Von hier aus finden wir erste Hinweise auf Programmierumgebungen, für die der „Binärmodus“ tatsächlich einen Unterschied macht:

#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

Scheinbar, __EMX__IstEberhard Mattes eXtender, eine 32-Bit-Programmierumgebung für MS-DOS und OS/2. Ebenso __DJGPP__bezieht sich auf dieDJGPP 32-Bit-Entwicklungssystem für MS-DOSUnd dann gibt es nochCygwin. Alle diese Programmierumgebungen basieren auf setmode()in deklarierten <io.h>.

Für andere Programmierumgebungen, die definieren O_BINARY, _setmode()wird (wie von der jeweiligen Programmierumgebung definiert) verwendet.

Ein Beispiel für Betriebssysteme, bei denen der Textmodus gegenüber dem Binärmodus wichtig sein kann, ist OpenVMS. Es kennt auch die Unix-artige Art, Text als einfachen Zeichenfolgenstrom zu speichern. In der OpenVMS-Welt ist dies anscheinend als Format bekannt Stream_LF- und die Tatsache, dass es einen bestimmten Namen hat, sollte ein Hinweis darauf sein, dass esnicht die einzige Möglichkeit, Textdateien zu formatieren.

Für Neugierige:http://neilrieck.net/docs/openvms_notes_text_files.html

Zusammenfassend lässt sich sagen, dass das non-stream simple textDateiformat in OpenVMS null oder mehr Datensätze (Zeilen) enthält, deren maximale Größe in den Dateimetadaten definiert ist (kann bis zu 32767 Bytes betragen). Jeder Zeile ist ein 16-Bit-Wert vorangestellt, der die Anzahl der Bytes in jeder Zeile angibt. So etwas wie ein „Zeilenendezeichen“ gibt es nicht: Eine Zeile endet, wenn die angegebene Anzahl von Bytes gelesen wurde. Wenn die Anzahl der Bytes in einer Zeile ungerade ist, 0x00wird ein Füllbyte hinzugefügt, um den Anfang der nächsten Zeile an einer wortbündigen Adresse zu haben. Dieses Füllbyte wird nie zur Zeilenlänge gezählt.

GNU Coreutils war sicherlichauf OpenVMS portiert.

Antwort3

Als Ergänzung möchte ich noch die Information hinzufügen, dass es unter Windows md5sumauch keinen Unterschied in der Berechnung --textoder --binaryim Modus gibt. Getestet auf md5sum(GNU coreutils) 8.31 für 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.

verwandte Informationen