md5sum コマンド バイナリおよびテキストモード

md5sum コマンド バイナリおよびテキストモード

GNUmd5sumコマンドには 2 つのモードがあります。バイナリモードと文章モード。違いは改行文字の処理方法だけだと思いますが、正しいでしょうか?

-bGNU/Linux では、2 つのモードは常に同じ結果を生成するため、およびオプションの使用は、ファイル名の前に使用される-tフラグ (*または) を示すためだけです。

どのような状況でモードによって結果が異なる可能性がありますか? Windows/MacOS システムの場合? (これらのプラットフォーム用のバージョンは利用可能ですか?)

答え1

GNU/Linuxでは、2つのモードは常に同じ結果を生成します。

はい、明確に。差出人man md5sum:

注記:GNU システムではバイナリ モード オプションとテキスト モード オプションに違いはありません。

これは、GNU coreutils 8.21 に同梱されている実装からのものですmd5sum。古いバージョン (8.12) にはこの通知がないことに気付きましたが、いずれにしても同じことが当てはまると思います。

AFAICT はmd5sum公式には標準化されていませんが (POSIX などによって)、さまざまなプラットフォームのさまざまな実装で利用でき、システム間での使いやすさのためにこれらを相互に準拠させる努力が行われていることは明らかです。

これに関連して、ISO/ANSI C 標準ファイルにアクセスするための高レベルのストリーム関数が含まれています。標準の一部として、これらは共有ライブラリまたはコンパイラを介して ISO C を実装するすべてのオペレーティング システムで使用できます。ほとんどすべてのオペレーティング システムでこれを使用できるため (オペレーティング システム自体もほとんどの場合 C で記述されている)、非常に移植性の高いソフトウェアを実装するために使用される一種の汎用言語です。

md5sumの機能を考えると、どのオペレーティングシステムでもコンパイルして動作する を書くことはまったく可能です。これは GNU coreutils バージョンに当てはまるとは言いませんが、前述の高レベル ファイル ストリーム関数の 1 つである はfopen()、ISO C によって、bファイルを開くときに「バイナリ ファイルとして」開かれていることを示すスイッチを含めることが義務付けられています。これが意味することやシステムに要求することは、ない標準規格で規定されているが、何らかの(どれでも) 理由を説明します。

Linux/POSIX/*nixスタイルのオペレーティングシステムではそのような理由はないので、スイッチは何もしません。POSIX仕様(ISO Cのスーパーセット)によると、fopen():

文字「b」は効果がありませんが、ISO C 標準準拠では使用できます。

したがって、完全に移植可能なmd5sum実装では、ISO C でファイルにアクセスするための他の方法がないため、ISO の高レベル ファイル ストリーム関数を使用する可能性があります (POSIX 準拠のものを含むほとんどのプラットフォームには、独自の低レベル メソッドもありますが、これらは ISO C にはないため、移植性がありません)。また、ファイルを読み取るときにオプションを追加するか追加しないかを指定する-bおよびフラグも実装する必要があります。それが無意味なシステムでは、違いはありません。-tbfopen()

もう一度言いますが、GNUのmd5sumが完全に移植可能な方法で書かれていたり、移植可能な方法から派生していると言っているわけではありませんが、明らかに、その操作性は移植可能な方法に準拠しようとしています。何もしないフラグを持つことは、フラグを持たないことと同じではないことに注意してください。前者の場合、フラグは問題ないが何もしないことが指定されていますが、後者の場合、フラグを使用するとエラーが発生したり、未定義の動作

答え2

他の人がすでに述べているように、GNU システムおよび最新の Windows では、これらのオプションはまったく効果がありません。

ソース コードを見ると、md5sumがファイルで使用される場合、テキスト/バイナリ オプションによって、modeで使用されるパラメータがfopen(const char *pathname, const char *mode)"r"かが決まります"rb"。すべての POSIX 準拠システムでは、 はb単に無視され、効果はありません。

md5sum標準入力を読み込むとcoreutilsデフォルトでテキストモードになります以下のすべてが当てはまる場合のみ:

  • コンパイル時マクロO_BINARYが定義されている(つまり、テキストモードとバイナリモードの間に違いがある)
  • 入力は端末から来ている
  • モードはコマンドライン オプションによって上書きされません。

それ以外の場合は、バイナリ モードが想定され (コマンドライン オプションによって上書きされない限り)、O_BINARY定義されている場合はxset_binary_mode()標準入力に対して呼び出されます。

xset_binary_mode()xbinary-io.hで定義されたラッパーgnulibが未定義の場合O_BINARY、それはダミー関数となり、優れた C コンパイラによって最適化されて削除されます。したがって、何らかの理由で関数が呼び出されたとしても、テキストとバイナリの違いは結局影響しません。

しかし、O_BINARYが定義されている場合、は で宣言されたxset_binary_mode()のラッパーになります。set_binary_mode()binary-io.hgnulibここから、「バイナリ モード」が実際に違いを生むプログラミング環境についての最初の手がかりが見つかります。

#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

どうやら、 __EMX__エバーハルト マッテス エクステンダー、MS-DOSおよびOS/2用の32ビットモードプログラミング環境。同様に__DJGPP__DJGPP MS-DOS 用 32 ビット開発システムそしてまたシグウィンこれらすべてのプログラミング環境は、setmode()で宣言されたものに依存しています<io.h>

を定義するその他のプログラミング環境ではO_BINARY_setmode()(それぞれのプログラミング環境で定義されている)が使用されます。

テキストモードとバイナリモードが重要になるオペレーティングシステムの例として、OpenVMSが挙げられます。OpenVMSは、テキストを文字のストリームとして保存するUnixスタイルの方法も認識しています。OpenVMSの世界では、これはフォーマットとして知られているようですStream_LF。特定の名前があるという事実は、それがフォーマットであることを示すヒントです。テキストファイルをフォーマットする唯一の方法ではない

興味がある方へ:http://neilrieck.net/docs/openvms_notes_text_files.html より

要約すると、OpenVMS のnon-stream simple textファイル形式には、最大サイズがファイル メタデータで定義されている 0 個以上のレコード (行) が含まれます (最大 32767 バイト)。各行の先頭には、各行のバイト数を示す 16 ビット値が付けられます。「行末文字」というものはありません。指定されたバイト数が読み取られると行が終了します。行のバイト数が奇数の場合、0x00次の行の先頭がワード境界のアドレスになるようにパディング バイトが追加されます。このパディング バイトは行の長さにカウントされません。

GNU Coreutilsは確かにOpenVMS に移植されました。

答え3

補足として、Windows でもモードmd5sumの計算に違いはないという情報を追加します。Windows用 (GNU coreutils) 8.31 でテスト済み。--text--binarymd5sum

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.

関連情報