GNUmd5sum
コマンドには 2 つのモードがあります。バイナリモードと文章モード。違いは改行文字の処理方法だけだと思いますが、正しいでしょうか?
-b
GNU/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
およびフラグも実装する必要があります。それが無意味なシステムでは、違いはありません。-t
b
fopen()
もう一度言いますが、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.h
のgnulib
ここから、「バイナリ モード」が実際に違いを生むプログラミング環境についての最初の手がかりが見つかります。
#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
--binary
md5sum
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.