md5sum 명령 바이너리 및 텍스트 모드

md5sum 명령 바이너리 및 텍스트 모드

GNU md5sum명령에는 두 가지 모드가 있습니다.바이너리모드와텍스트방법. 개행 문자를 처리하는 방법에만 차이점이 있다고 생각합니까? 내가 맞나요?

GNU/Linux에서 두 모드는 항상 동일한 결과를 생성하므로 -b및 옵션의 유일한 사용은 파일 이름 앞에 사용된 -t플래그( *또는 )를 나타내는 것입니까?

어떤 상황에서 모드에 따라 다른 결과가 나타날 수 있습니까? Windows/MacOS 시스템에서요? (이 플랫폼에 대한 버전을 사용할 수 있습니까?)

답변1

GNU/Linux에서는 두 모드가 항상 동일한 결과를 생성합니다.

예, 명시적으로요. 에서 man md5sum:

메모:[sic] GNU 시스템에서는 바이너리 모드 옵션과 텍스트 모드 옵션 사이에 차이가 없습니다.

이는 md5sumGNU coreutils 8.21과 함께 제공되는 구현에서 나온 것입니다. 이전 버전(8.12)에는 이 알림이 없다는 것을 알았지만 어쨌든 마찬가지일 것이라고 생각합니다.

AFAICT는 md5sum공식적으로 표준화되지 않았지만(예: POSIX에 의해) 다양한 플랫폼에서 다양한 구현으로 사용할 수 있으며 시스템 전체에서 사용하기 쉽도록 서로 호환되도록 하기 위한 노력이 분명히 있습니다.

이와 관련하여,ISO/ANSI C 표준파일 액세스를 위한 고급 스트림 기능이 포함되어 있습니다. 이는 표준의 일부로 공유 라이브러리나 컴파일러를 통해 ISO C를 구현하는 모든 운영 체제에서 사용할 수 있습니다. 거의 모든 운영 체제에서 이를 사용할 수 있기 때문에(C로 가장 자주 작성됨) 잠재적으로 이식성이 뛰어난 소프트웨어를 구현하는 데 사용되는 일종의 범용 언어입니다.

md5sum그것이 하는 일을 고려하면, 모든 운영 체제에서 컴파일하고 작동하는 것을 작성하는 것이 완전히 가능합니다 . 나는 이것이 GNU coreutils 버전에 해당한다고 주장하는 것이 아니지만 앞서 언급한 높은 수준의 파일 스트림 기능 중 하나는 ISO C에서 파일을 여는 데 사용되는 스위치를 fopen()포함하도록 요구하는 것 입니다. b파일". 이것이 시스템에 의미하거나 요구하는 것그렇지 않다표준에 규정되어 있으므로 일부가 있을 수 있는 시스템에서 사용할 수 있도록 존재해야 합니다(어느) 그 이유는.

linux/POSIX/*nix 스타일 운영 체제에는 그러한 이유가 없으므로 스위치는 아무 작업도 수행하지 않습니다. POSIX 사양(ISO C의 상위 집합)에서fopen():

문자 'b'는 아무런 영향을 미치지 않지만 ISO C 표준 준수에는 허용됩니다.

따라서 완전히 이식 가능한 md5sum구현에서는 ISO 상위 수준 파일 스트림 기능을 사용할 수 있습니다. ISO C에서는 파일에 액세스하는 다른 방법이 없기 때문입니다(POSIX 호환 플랫폼을 포함한 대부분의 플랫폼에는 자체 하위 수준 방법도 있지만 이러한 방법을 사용하면 ISO C가 아니기 때문에 이식성이 없습니다. 또한 파일을 읽을 때 옵션을 추가하거나 추가하지 않으려면 -b및 플래그도 구현해야 합니다. 이것이 의미가 없는 시스템에서는 아무런 차이가 없습니다.-tbfopen()

다시 말하지만, GNU의 md5sum이 완전히 이식 가능한 방식으로 작성되었거나 이식 가능한 방식에서 파생되었다고 말하는 것은 아닙니다. 그러나 분명히 작동성 면에서 이식 가능한 방식을 따르려고 노력하고 있습니다. 아무것도 하지 않는 플래그를 갖는 것은 플래그를 갖지 않는 것과 같지 않습니다. 전자의 경우에는 괜찮지만 아무것도 하지 않는 것으로 지정되는 반면, 후자의 경우에는 이를 사용하면 오류가 발생하거나 다음으로 이어질 수 있습니다.정의되지 않은 동작.

답변2

다른 사람들이 이미 언급했듯이 GNU 시스템과 최신 Windows에서는 이러한 옵션이 전혀 효과가 없습니다.

소스 코드를 보면 md5sum파일과 함께 사용되는 경우 텍스트/바이너리 옵션에 따라 mode사용되는 매개 변수가 또는 가 fopen(const char *pathname, const char *mode)될지 여부가 결정됩니다 . 모든 POSIX 규격 시스템에서는 이 단순히 무시되고 아무런 효과가 없습니다."r""rb"b

md5sum표준 입력을 읽는 경우 coreutils기본적으로 텍스트 모드로 설정됩니다.다음 사항이 모두 참인 경우에만:

  • 컴파일 타임 매크로가 O_BINARY정의됩니다(즉, 텍스트 모드와 바이너리 모드 사이에 차이가 있습니다).
  • 입력이 터미널에서 옵니다
  • 모드는 명령줄 옵션으로 재정의되지 않습니다.

그렇지 않으면 이진 모드가 가정되고(명령줄 옵션으로 재정의되지 않는 한) O_BINARY정의된 경우 xset_binary_mode()표준 입력에 대해 호출됩니다.

xset_binary_mode()~이다xbinary-io.hof 에 정의된 래퍼입니다 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파일 형식에는 파일 메타데이터에 최대 크기가 정의된 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.

관련 정보