메모장이있는 JPG 그림을 열고 모든 "텍스트"를 새 메모장 파일에 붙여넣고 .JPG로 변경했는데 더 이상 열리지 않습니다. 왜?


82

이 현상은 나에게 질문을 남겼습니다.

자세한 실험은 다음과 같습니다. 내 OS는 Windows 7 x64 SP1입니다.

  • 확장자를 변경하여 그림 (JPG) 파일을 TXT로 변경했습니다 (또는 메모장으로 JPG를 열 수도 있습니다).

다음과 같이 생겼습니다. 이상하게 보이는 텍스트 시퀀스와 그 중 일부 (매우 드문 경우)는 아래 스크린 샷에서와 같이 실제로는 의미가 있습니다. "작성자 : dg-jpeg v1.0 ..."

샘플 JPG 텍스트

  • 줄 바꿈을 비활성화하고 Ctrl + A를 사용하여 모든 텍스트를 선택했습니다 (아무것도 놓치지 않도록)
  • 복사 한 텍스트를 다른 빈 TXT 파일에 붙여넣고 JPG로 저장했습니다. 새 파일 크기를 원래 JPG와 비교했습니다. 이들 모두 (원본 JPG, 변환 된 TXT 파일 및 새로 작성된 TXT 파일)는 바이트와 정확히 동일한 크기입니다.

열려고하면 Windows에서 "파일이 손상되었거나 손상되었거나 너무 커서 Windows 사진 뷰어에서이 사진을 열 수 없습니다"라고 말합니다 .

난 다른 방법을 사용하여 테스트하려고 : 메모장으로 JPG를 개설, 나는 잘라 ONE 다음 파일을 저장 (2 줄의 첫 번째 문자 등) 기억하기 쉬운 위치에서 알려진 문자. 뷰어는 물론 동일한 메시지를 표시합니다. 그런 다음 다시 열어서 문자를 정확한 위치에 붙여 넣었습니다 (메모장은 창 위치, 줄 바꿈, 글꼴 크기와 같은 종료 상태를 기억합니다 ... 그래서이 문제를 해결하는 데 아무런 문제가 없습니다)

그리고 여전히 같은 오류입니다. 당신은 아이디어를 얻기 위해 이것을 시도 할 수 있습니다. 작은 그림을 선택하는 것을 기억하십시오. 그렇지 않으면 메모장은 늙은 녹슨 사람처럼 행동 할 것입니다.

이 현상의 원인은 무엇입니까?


4
fc 명령을 시도하십시오. cmd 프롬프트를 열고 do- C:\blah>fc file1 file2 파일의 크기는 같지만 다를 수 있습니다. (일반적으로 일부 임의 변경은 파일의 크기를 동일하게 유지하지 않지만 쉽게 할 수 있습니다). fc 명령은 무슨 일이 일어나고 있는지 조사하는 데 매우 유용합니다. xxd 명령을 사용할 수도 있습니다.이 명령은 cygwin에 있으며 vim7과 함께 제공됩니다. xxd -p file1 파일의 16 진을 덤프합니다. 두 파일의 16 진을 해당 파일과 fc와 비교할 수 있습니다. 또는 메모장에서 16 진수를 열고 alt-tab을 사용하여 두 개의 메모장 창 사이를 쓸어 넘기십시오.
barlop

22
메모장과 같은 간단한 텍스트 편집기로 이진 파일을 읽으려고합니다. ANSI 인코딩을 올바르게 읽을 수 없으므로 변환됩니다. 파일을 저장하면 파일은 더 이상 바이너리가 아니므로 파서는 파일 내부의 데이터를 읽을 수 없습니다. (XML 기반 파일 저장과 이진 파일 저장의 차이점을 살펴보면 흥미로운 주제입니다.) Notepad ++로 동일한 실험을 시도하면 시도한 작업에서 성공할 수 있습니다.
woutervs


3
Vim에서 이미지를 편집 할 수 있습니다. 그러나 Vim은 파일을 XPM 형식 (일반 ASCII)으로 변환합니다 .
Boldewyn

4
간단히 말해 메모장은 파일을 표시하기 전에 파일을 수정합니다.
Derek 朕 會 功夫

답변:


81

파일을 여는 데 사용 된 인코딩에 따라 다른 동작이 나타날 수 있습니다. 내 Windows 7 메모장에서 ANSI, UTF-8, 유니 코드 또는 유니 코드 빅 엔디안으로 파일을 열 수 있습니다.

김프로 만든 작은 2x2 픽셀 JPEG 이미지로 ANSI 인코딩으로 이미지 파일을 열고 저장 하여이 문제를 테스트했습니다. 16 진수 편집기로 원본 이미지와 저장된 이미지를 모두 열면 00 개의 모든 시퀀스 (2 개의 16 진수, NUL 제어 문자 )가 20 (공백 문자)으로 변환 된 것을 알 수 있습니다.

16 진수 편집기에서 20 x 00으로 다시 바꾸면 이미지 형식이 복원됩니다.

나는 그것을 조금 봤는데 왜 그렇게하는지 설명하는 참조를 찾지 못했습니다. 게시물에 대한 참조경고합니다 (Google 캐시 링크, 페이지를 사용할 수 없음).

파일을 UTF-8로 저장 / 열면 여전히 NUL 문자를 공백으로 변환하는 것처럼 보이지만 1 바이트 문자에서 UTF-8 멀티 바이트 시퀀스로의 변환으로 인해 결과 파일 크기도 증가합니다.

파일을 유니 코드로 저장 / 열면 여전히 NUL 문자를 공백으로 변환하지만 파일의 시작 부분 인 BOM에 바이트를 추가하는 것 같습니다 .


22
0x00은 C 문자열의 문자열 종결 자입니다. 텍스트 파일에 포함되지 않아야하므로 대체했을 수 있습니다. 메모장은 매우 오래된 프로그램입니다.
Zonder

25
notepad.exe가 .NET 실행 파일인지 의심합니다.
knittl

10
@Bakuriu AC 문자열이 가장 확실하게 파일에 존재할 수 있습니다. 나는 그것들을 포함하는 수많은 파일 형식을 생각할 수 있습니다. 또한 Windows 앱과 함께 제공되는 대부분의 앱은 .NET이 아니라 기본 앱입니다. 메모장은 null로 끝나는 문자열을 파일에 쓰지 않습니다.
캐리 그레고리

4
@Bakuriu : Windows 프로그램은 일반적으로 .Net으로 작성되지 않습니다. C / C ++이며 핵심입니다. Microsoft에서 개발 한 .Net 응용 프로그램 중 하나는 현재 중단 된 라이브 라이터였습니다.
bhathiya-perera

5
@ SJuan76 응? C ++는라는 데이터 유형을 정의하지 않습니다 byte. 아마도 당신은 다른 언어를 생각하고있을 것입니다. 또한 응용 프로그램 개발자는 이진 데이터를 처리 할 수 ​​있지만 원하는 경우 C 문자열 사용을 포함하여 적합하다고 생각됩니다. 앞에서 말했듯이 C 문자열을 포함하는 수많은 이진 파일 형식을 생각할 수 있습니다.
캐리 그레고리

37

실패한 이유 :

Windows API의 텍스트 상자는 널 종료 ASCIIZ (문자 배열, 포인터) 만 허용하므로 메모장 (ASCII code 32)NUL 과 같은 문자에 공백 문자를 만듭니다 . 첫 번째 NUL에서 잘립니다.(ASCII code 0)char *

때문이 발생 윈도우 API는 대부분 작성된 C의 언어와 널 (null) 문자열이 종료 일반적인 기능 중 하나입니다. 최신 Windows 및 유니 코드가 동일한 것으로 간주 되더라도 널 종료 문자열이 발생합니다. 메모장은 단순히 공간으로 대체하여 전체 파일을 볼 수 있습니다.

따라서 파일을 저장하면 파일이 손상됩니다.

wikipedia null로 끝나는 문자열


추가 연구 방법 :

비교 (상업용, 시험판) 이외 의 비교기를 사용 하여 문자 교체 효과를 볼 수 있습니다. 다른 이진 비교 도구 도 참조하십시오 .

16 진 비교

참고 : (20) 16 = (32) 10


큰 파일에서 메모장이 느리게 작동하는 이유

각 문자를 확인하고 특수 문자를 공백으로 바꿉니다. 다른 소프트웨어는 메모리 내 변환을 수행하지 않습니다 (적어도 기본적으로 메모장은 아님). 특수 문자를 다르게 렌더링합니다. 그리고 고급 버퍼링 기술을 사용합니다.


Notepad.exe (XP 32 비트) 살펴보기

(나는 여전히 C ++로 작성되었거나 적어도 비슷한 링커를 사용한다고 가정합니다 )

메모장

PEiD 도구를 사용하고 있습니다 (PE + / 64 exe를 도입하여 개발을 중단했습니다)

PEiD는 Universal Extractor 의 bin 폴더에 번들로 제공됩니다.

메모장을 추출했습니다. Windows XP iso의 ex_ 파일은 분명합니다. 사용해보십시오. 7z를 사용하는 택시 파일 추출입니다.

경고! 바이러스 스캐너가 Universal Extractor / PEiD를 해킹 도구 또는 바이러스로 탐지 할 수 있습니다. 그것을 다운로드하지 마십시오 믿지 마세요!


Windows API에 대한 추가 정보

크레딧 : Jason C

텍스트 상자 만이 아닙니다. 일반적으로 WM_SETTEXT 는 문자열 길이를 지정하기위한 매개 변수를 제공하지 않으며 문자열은 항상 null로 끝나는 것으로 가정합니다. 문자열 길이를 지정하는 사용자 지정 메시지를 사용하여 항상 사용자 지정 텍스트 상자를 만들 수 있지만 메모장 및 대부분의 다른 프로그램은 그렇지 않습니다. 또한 SetWindowText 함수 는 길이 매개 변수도 제공하지 않습니다.


1
Windows XP 버전과 함께 번들로 제공되는 메모장 실행 파일의 속성 시트를 표시하지만 창 테마로 판단하면 일부 Windows 8 버전을 명확하게 실행하는 것이 조금 이상합니다. 버전 7.1의 도구 세트 —Windows XP 및 관련 유틸리티를 컴파일하는 데 사용 된 도구입니다. 메모장의 Windows 8 버전은 의심 할 여지없이 최신 버전의 SDK 도구로 컴파일됩니다.
코디 그레이

2
텍스트 상자 만이 아닙니다. WM_SETTEXT일반적으로 문자열 길이를 지정하기위한 매개 변수를 제공하지 않으며 문자열은 항상 null로 종료되는 것으로 가정합니다. 문자열 길이를 지정하는 사용자 지정 메시지를 사용하여 항상 사용자 지정 텍스트 상자를 만들 수 있지만 메모장 및 대부분의 다른 프로그램은 그렇지 않습니다.
Jason C

@BhathiyaPerera 의견에 정보를 추가하여 수행 한 작업 수준에 만족하기 때문입니다. 원하는 경우 해당 정보로 답변을 개선 할 수 있습니다.
Jason C

28

메모장은 모든 특수 / 확장 문자를 그대로 유지하지는 않습니다. 나는이 동작에 대한 참조를 즉시 가지고 있지 않지만 메모장과 같은 CRLF로 변환되는 UNIX 스타일 줄 LF의 경우와 같이 무시할 null (0x00)과 같은 경우를 발견했습니다. JPG와 같은 이진 파일에서 메모장이 유지하지 않는 문자가 임의로 발생할 수 있습니다. HEX 인식 편집기로 실험 해보십시오. 그러면 제대로 작동합니다. 좋은 참조를 찾으면 HEX 편집기를 테스트 한 후에 답변을 업데이트하겠습니다.

업데이트 : 나는 잘 알려진 프로그래머 편집자를 시도했지만 그중 한 명만이 Maël Hörz의 HxD를 사용했습니다 . 이전에 HxD를 사용한 적이 없지만이 스택 기사, 메모장 ++ 용 16 진수 뷰어 / 편집기 플러그인에 대한 답변 덕분에 HxD를 발견했습니다 .

몇 분의 노력 끝에 작동하지 않은 다른 편집기는 Notepad ++, Notepad2 및 UltraEdit (v17.3, 이전 버전)입니다. 이 중 몇 개는 처음 몇 바이트의 복사 / 붙여 넣기 (JPEG 파일 서명 매직 번호 FF D8 FF)에 문제가있었습니다. 어쩌면 그들은 현재 시간보다 조금 더 어리석은 일을 할 것입니다.


Sublime Text (2/3)는 이진 파일을 16 진 형식으로 표시하여 자동으로 엽니 다. 예를 들어, "열기"를 클릭하여 JPEG 파일의 시작 : puu.sh/aaAVx/bd08dab46e.png
tomsmeding

3
실제로 메모장보다 LF를 CRLF로 변환하는 것보다 LF를 그대로 유지하고 줄 바꿈이없는 것처럼 텍스트를 표시합니다!
Moshe Katz

6

예전에는 다시 쓰기를 사용하여이 작업을 수행 할 수있었습니다. Windows 3.1의 표준 프로그램이지만 Windows 95에 포함되어 있는지 기억할 수 없습니다. 쓰기는 파일을 열 수있는 바이너리의 안전한 편집을 가능하게합니다 (아마도 파일 크기가 매우 제한적 임). 메모장은 분명히 바이너리 안전하지 않습니다 (텍스트는 동일하지만 텍스트가 아닌 문자 (예 : 제어 코드)의 실제 바이트는 변경 될 수 있습니다) .JPG 예제가 작동하지 않는 이유입니다. Write (그리고 아주 오래된 Windows) 사본을 받고 실험을 다시 시도하십시오!

Wikipedia의 "Windows Write"기사 에 따르면 Write는 Windows NT 3.5까지 포함되었습니다. Windows 95부터 Wordpad로 대체되었습니다. write.exe여전히 Windows 디렉토리에 있지만 Wordpad를 열기위한 래퍼 일뿐입니다.


5

나는 인코딩의 문제가 아니라 문자 세트의 문제라고 생각합니다. JPG 형식은 기본적으로 바이트 스트림입니다. 따라서 NUL, ETX, STX, SOH, DLE 등과 같은 인쇄 할 수없는 문자를 허용합니다.

Microsoft 메모장은 인쇄 할 수없는 문자를 표시 할 수 없습니다. 널 문자를위한 공간과 같은 일종의 플레이스 홀더를 표시 할 수 있습니다. 따라서 메모장을 사용하여 파일을 열면 실제 내용은 표시되지 않지만 선택한 인코딩 (utf-8, utf-16 등)으로 디코딩되고 비 문자를 제외한 특정 문자 세트 (유니 코드, ASCII 등)로 표시되는 내용 인쇄 가능한 문자.

표시된 모든 텍스트를 선택하고 텍스트를 클립 보드에 복사 할 때는 자리 표시자를 포함하여 인쇄 가능한 문자 만 복사합니다. 따라서 널 문자를 공백으로 자동 변환하고 인쇄 할 수없는 다른 문자는 완전히 무시합니다.

따라서 기본적 으로이 방법으로 콘텐츠를 잃어 버립니다. 16 진수 편집기를 대신 사용하면 모든 내용이 완전히 복사됩니다.


업데이트 : Bhathiya Pereras 답변이 옳습니다 : https://superuser.com/a/782885/322784 텍스트를 클립 보드에 복사 할 때 인쇄 할 수없는 문자는 무시되지 않습니다.


모든 파일은 "기본적으로 바이트 스트림"입니다.
Jason C

1
@JasonC 나는 동의하지 않을 것이다. 모든 파일을 바이트 스트림으로 읽을 수 있습니다. XML 파일과 같은 구조화 된 파일은 데이터 스트림으로 읽을 수 없습니다. 파일 끝을 읽을 때까지 내용이 유효하지 않습니다. 반으로 자른 jpg는 여전히 유효하며 표시 할 수 있습니다. 사진의 절반이 누락되었습니다.
sbecker

그에 대한 의견의 여지가 실제로 없습니다. :) XML은 다른 것과 마찬가지로 바이트 스트림이며 XML (문자 인코딩과 함께)은 해당 바이트의 형식을 정의합니다. 확실히 데이터 스트림으로 읽을 수 있습니다. 예를 들어 16 진 편집기에서여십시오. 이 데이터 스트림은 XML로 구문 분석 할 수 있습니다.
Jason C

@JasonC 실제로는 논쟁 할 수 없습니다. :) Touché!
sbecker

2

JPEG 파일에는 일부 필드를 제외하고 텍스트가 아닌 데이터가 포함되어 있습니다. 특히 의사 난수 데이터가 거의 포함 된 인코딩 된 압축 이미지를 나타내는 영역에서 기본적으로 0에서 255 사이의 바이트 값이 있습니다.

그러나 메모장은 기본적으로 데이터를 ANSI 텍스트로 취급하므로 다음과 같이 원본 데이터를 변경하는 다양한 작업을 수행합니다.

  • 특수 / 정의되지 않은 / 금지 된 문자를 매핑하는 바이트를 대체하십시오. 유효한 ANSI 텍스트에는 적합하지 않습니다.

  • 널 문자, 줄 끝 및 파일 시퀀스 끝을 Windows / DOS 규칙으로 다시 인코딩

즉, 데이터를 텍스트로 편집하고 저장하면 jpeg가 변경되고 최악의 경우에는 사용할 수 없게됩니다.


"ANSI" 는 일반적으로 이해되지만 기술적으로 정확하지 않습니다 .
Jason C
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.