GNU md5sum
명령에는 두 가지 모드가 있습니다.바이너리모드와텍스트모델. 차이점은 개행 문자를 처리하는 방법이라고 생각합니다. 내가 맞나요?
GNU/Linux에서는 두 모드 모두 항상 동일한 결과를 생성하므로 및 옵션의 유일한 목적은 파일 이름 ( 또는 ) -b
앞에 사용되는 플래그를 나타내는 것입니다 .-t
*
어떤 상황에서 이러한 패턴이 다른 결과를 낳습니까? Windows/MacOS 시스템을 사용하시나요? (이러한 플랫폼에 사용할 수 있는 버전이 있습니까?)
답변1
GNU/Linux에서는 두 모드 모두 항상 동일한 결과를 생성합니다.
예, 명시적으로요. 에서 man md5sum
:
노트:[sic] GNU 시스템에서는 바이너리 모드 옵션과 텍스트 모드 옵션 사이에 차이가 없습니다.
이것은 md5sum
GNU coreutils 8.21과 함께 제공되는 구현에서 나온 것입니다. 이전 버전(8.12)에는 이 알림이 없다는 것을 알았지만 어쨌든 그럴 것이라고 가정합니다.
AFAICT는 md5sum
공식적으로 표준화되지 않았지만(예: POSIX를 통해) 다양한 구현을 통해 다양한 플랫폼에서 사용할 수 있으며 시스템 전반에서 쉽게 사용할 수 있도록 이러한 플랫폼을 서로 호환되게 만들려면 분명히 약간의 노력이 필요할 것입니다.
이와 관련하여,ISO/ANSI C 표준파일 액세스를 위한 고급 스트리밍 기능이 포함되어 있습니다. 이는 표준의 일부로 공유 라이브러리나 컴파일러를 통해 ISO C를 구현하는 모든 운영 체제에서 사용할 수 있습니다. 이 기능은 거의 모든 운영 체제에서 사용할 수 있으므로(자체는 C로 작성되는 경우가 많음) 이식성이 매우 뛰어난 소프트웨어를 구현하기 위한 범용 언어입니다.
md5sum
그 기능을 고려하면 모든 운영 체제에서 컴파일하고 실행되는 프로그램을 작성하는 것이 전적으로 가능합니다. GNU coreutils 버전에서도 마찬가지라고 말하는 것은 아니지만 앞서 언급한 상위 수준 파일 스트림 기능 중 하나는 fopen()
ISO C에서 파일 열기 스위치를 포함하여 b
"파일 열기"를 표시하도록 요구하는 기능입니다. 바이너리 파일로". 이것이 의미하는 바 또는 시스템 요구 사항은 무엇입니까?아니요표준에서는 일부(어느)의 이유.
linux/POSIX/*nix 스타일 운영 체제에는 그러한 이유가 없으므로 이 스위치는 아무 작업도 수행하지 않습니다. POSIX 사양(ISO C의 상위 집합)에서열려 있는():
문자 'b'는 유효하지 않지만 ISO C 표준을 준수하는 것이 허용됩니다.
따라서 md5sum
ISO C의 파일에 액세스하는 다른 방법이 없기 때문에 완전히 이식 가능한 구현에서는 ISO 상위 수준 파일 스트림 기능을 사용할 수 있습니다(POSIX 호환 플랫폼을 포함한 대부분의 플랫폼에도 자체 하위 수준 방법이 있지만 이러한 메소드는 ISO C에 없기 때문에 이식성이 없으며 -b
파일을 읽을 때 옵션을 -t
추가하거나 추가하지 않도록 플래그도 구현해야 합니다 b
. fopen()
말이 안되는 시스템에서는 아무런 차이가 없습니다.
다시 말하지만, GNU의 md5sum이 완전히 이식 가능한 방식으로 작성되었거나 파생되었다고 말하는 것은 아닙니다. 그러나 분명히 조작성 측면에서 이러한 방식을 고수하려고 합니다. 아무것도 하지 않는 플래그가 있는 것과 없는 것은 다릅니다. 전자의 경우에는 수행하도록 지정되었지만 아무 작업도 수행하지 않는 반면, 후자의 경우 이를 사용하면 오류가 발생하거나 원인이 될 수 있습니다.정의되지 않은 동작.
답변2
다른 사람들이 지적했듯이 GNU 시스템과 최신 Windows에서는 이러한 옵션이 효과가 없습니다.
소스 코드를 보면 md5sum
파일과 함께 사용될 때 text/binary 옵션이 mode
or에서 사용되는 인수를 결정합니다. 모든 POSIX 호환 시스템에서는 무시되며 아무런 효과도 없습니다.fopen(const char *pathname, const char *mode)
"r"
"rb"
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__
예에버하르트 마테스 eXtender, MS-DOS 및 OS/2용 32비트 모드 프로그래밍 환경입니다. 마찬가지로 __DJGPP__
다음을 가리킨다 .MS-DOS용 DJGPP 32비트 개발 시스템. 그리고 거기에는시빈. 이러한 프로그래밍 환경 setmode()
은 모두 <io.h>
.
O_BINARY
정의 된 다른 프로그래밍 환경의 경우 _setmode()
(해당 프로그래밍 환경에 의해 정의됨)이 사용됩니다.
OpenVMS는 텍스트 모드와 바이너리 모드의 운영 체제의 중요한 예 중 하나입니다. 또한 텍스트를 간단한 문자 스트림으로 저장하는 Unix 스타일 방식도 알고 있습니다. OpenVMS 세계에서는 이것을 분명히 부릅니다 Stream_LF
. 특정 이름이 있다는 사실은 이것이텍스트 파일의 형식을 지정하는 유일한 방법은 아닙니다.
궁금하신 분들을 위해:http://neilrieck.net/docs/openvms_notes_text_files.html
요약하면 OpenVMS에서 non-stream simple text
파일 형식에는 파일 메타데이터에 정의된 최대 크기(최대 32767바이트)와 함께 0개 이상의 레코드(라인)가 포함됩니다. 각 줄에는 각 줄의 바이트 수를 나타내는 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.