Đã mở một hình ảnh JPG bằng notepad, dán tất cả các văn bản trên máy tính vào một tập tin notepad mới, đổi thành .JPG và nó không còn mở ra nữa. Tại sao?


82

Hiện tượng này đã để lại cho tôi câu hỏi để hỏi.

Dưới đây là thử nghiệm chi tiết, hệ điều hành của tôi là Windows 7 x64 SP1:

  • Tôi đã thay đổi tệp hình ảnh (JPG) thành TXT bằng cách thay đổi tiện ích mở rộng của nó (hoặc người ta chỉ có thể chọn mở JPG bằng notepad, điều tương tự)

Nó trông giống như thế này, các chuỗi văn bản trông kỳ quặc và một số trong số chúng (rất hiếm) thực sự có ý nghĩa, như trong ảnh chụp màn hình bên dưới "creator: dg-jpeg v1.0 ..."

Văn bản JPG mẫu

  • Tôi đã tắt gói và chọn tất cả văn bản bằng Ctrl + A (để đảm bảo không bỏ sót nội dung nào)
  • Tôi đã dán văn bản đã sao chép vào một tệp TXT trống khác và lưu nó dưới dạng JPG, tôi so sánh kích thước tệp mới với JPG gốc. Tất cả trong số họ (những JPG gốc, các tập tin TXT chuyển đổi và file TXT mới được tạo ra) là của chính xác kích thước tương tự, để byte.

Khi tôi cố mở, Windows sẽ nói "Windows Photo Viewer không thể mở ảnh này vì tệp dường như bị hỏng, bị hỏng hoặc quá lớn" .

Tôi thậm chí đã thử kiểm tra nó bằng một phương pháp khác: Mở JPG bằng notepad, tôi cắt MỘT ký tự đã biết từ một vị trí dễ nhớ (như ký tự đầu tiên của dòng thứ 2) sau đó lưu tệp. Người xem tất nhiên sẽ hiển thị cùng một thông điệp. Sau đó, tôi mở lại và dán ký tự vào vị trí CHÍNH XÁC (Notepad nhớ trạng thái thoát của nó như vị trí cửa sổ, gói, kích thước phông chữ ... vì vậy tôi không gặp vấn đề gì khi nói đúng)

Và vẫn là lỗi tương tự. Bạn có thể thử điều này để có được ý tưởng, hãy nhớ chọn một hình ảnh nhỏ khác Notepad sẽ hoạt động như một người đàn ông rỉ sét cũ.

Điều gì có thể là nguyên nhân của hiện tượng này?


4
Hãy thử lệnh fc. mở một dấu nhắc cmd và làm- C:\blah>fc file1 file2 Có thể các tệp có cùng kích thước nhưng khác nhau. (mặc dù thông thường một số thay đổi ngẫu nhiên không có xu hướng để lại một tệp có cùng kích thước nhưng nó có thể dễ dàng có thể). Lệnh fc sẽ rất hữu ích cho bạn trong việc điều tra những gì đang xảy ra. Bạn cũng có thể sử dụng lệnh xxd, đây là trong cygwin và cũng đi kèm với vim7. xxd -p file1 Điều đó sẽ kết xuất hex của một tập tin. Bạn có thể so sánh hex của hai tệp với đó và fc. Hoặc thậm chí mở hex trong notepad và vuốt giữa hai cửa sổ notepad bằng tab alt.
barlop

22
Bạn đang cố đọc một tệp nhị phân với trình soạn thảo văn bản đơn giản như notepad. Nó sẽ không thể đọc mã hóa ANSI một cách chính xác và do đó nó sẽ chuyển đổi nó. Khi bạn lưu nó thì tệp sẽ không còn là nhị phân nữa và do đó trình phân tích cú pháp không thể đọc dữ liệu bên trong tệp. (Tra cứu sự khác biệt giữa lưu tệp dựa trên XML và lưu tệp nhị phân là một chủ đề thú vị.) Nếu bạn thử cùng một thử nghiệm với Notepad ++, bạn sẽ thành công trong những gì bạn đang thử.
đồ trang trí


3
Đối với người quan tâm: Bạn có thể chỉnh sửa hình ảnh trong Vim: Tuy nhiên, mẹo là, Vim chuyển đổi tệp theo định dạng XPM , là ASCII đơn giản.
Boldewyn

4
Câu chuyện dài, Notepad sửa đổi tệp của bạn trước khi hiển thị nó cho bạn.
Derek 朕 會

Câu trả lời:


81

Tùy thuộc vào mã hóa được sử dụng để mở tệp, bạn có thể thấy hành vi khác nhau. Sổ ghi chép Windows 7 của tôi cho phép mở một tệp bằng ANSI, UTF-8, Unicode hoặc Unicode endian.

Tôi đã kiểm tra vấn đề này với một hình ảnh jpeg 2x2 pixel nhỏ được tạo bằng gimp và mở và lưu tệp hình ảnh bằng mã hóa ANSI. Mở cả ảnh gốc và ảnh đã lưu bằng trình chỉnh sửa hex Tôi thấy rằng tất cả 00 chuỗi (hai chữ số hex, ký tự điều khiển NUL ) đã được chuyển đổi thành 20 (ký tự khoảng trắng).

Thay thế trở lại trong trình chỉnh sửa hex tất cả 20 by 00 khôi phục định dạng hình ảnh.

Tôi đã googled nó một chút và tôi đã không tìm thấy bất kỳ tài liệu tham khảo nào giải thích tại sao nó làm điều đó. Chỉ một tài liệu tham khảo cho một bài đăng cảnh báo về nó (liên kết bộ nhớ cache của google, trang không có sẵn).

Nếu bạn lưu / mở tệp dưới dạng UTF-8, có vẻ như nó vẫn chuyển đổi các ký tự NUL thành khoảng trắng nhưng nó cũng làm tăng kích thước tệp kết quả do chuyển đổi từ các ký tự một byte thành chuỗi nhiều byte UTF-8.

Nếu bạn lưu / mở tệp dưới dạng Unicode, có vẻ như nó vẫn chuyển đổi các ký tự NUL thành khoảng trắng nhưng cũng thêm một byte vào đầu tệp, BOM .


22
0x00 là một bộ kết thúc chuỗi trong chuỗi C. Họ có thể đã thay thế chúng vì một tệp văn bản không nên chứa chúng. Notepad là một chương trình rất cũ.
Zonder

25
Tôi nghi ngờ rằng notepad.exe là một tệp thực thi .NET.
knittl

10
@Bakuriu Chuỗi AC chắc chắn có thể tồn tại trong một tệp; Tôi có thể nghĩ về nhiều định dạng tập tin có chứa chúng. Và phần lớn các ứng dụng đi kèm với các ứng dụng Windows là bản địa, không phải .NET. Điều đó nói rằng, notepad không ghi các chuỗi kết thúc null vào các tệp.
Carey Gregory

4
@Bakuriu: Các chương trình Windows thường không được viết bằng .Net. Đó là C / C ++ và bản địa là cốt lõi. Một trong những ứng dụng .Net được phát triển bởi microsoft là nhà văn trực tiếp hiện đã ngừng sử dụng.
bhathiya-perera

5
@ SJuan76 Hả? C ++ không định nghĩa một kiểu dữ liệu có tên byte. Có lẽ bạn đang nghĩ về một số ngôn ngữ khác. Và các nhà phát triển ứng dụng có thể xử lý dữ liệu nhị phân theo cách họ thấy phù hợp, bao gồm cả việc sử dụng chuỗi C nếu họ chọn. Như tôi đã nói trước đây, tôi có thể nghĩ về nhiều định dạng tệp nhị phân có chứa chuỗi C.
Carey Gregory

37

Tại sao nó thất bại:

Notepad tạo (ASCII code 32)ký tự khoảng trắng cho các ký tự như NUL (ASCII code 0) vì hộp văn bản của API Windows chỉ cho phép char * nullI kết thúc (mảng ký tự, con trỏ). Nó bị cắt ở NUL đầu tiên.

Điều đó xảy ra vì API Windows chủ yếu được viết bằng ngôn ngữ Ccác chuỗi kết thúc null là một trong những tính năng phổ biến. Ngay cả khi Windows và Unicode hiện đại được coi là cùng một chuỗi kết thúc null. Vì vậy, notepad chỉ cần thay thế chúng bằng không gian để bạn có thể xem tập tin hoàn chỉnh.

Vì vậy, khi bạn lưu tập tin, nó bị hỏng.

chuỗi kết thúc wikipedia-null


Làm thế nào để nghiên cứu thêm:

Bạn có thể sử dụng một bộ so sánh như ngoài so sánh (thương mại, dùng thử) để xem hiệu ứng thay thế nhân vật. cũng thấy các công cụ so sánh nhị phân khác .

so sánh hex

Lưu ý : (20) 16 = (32) 10


Lý do cho notepad hoạt động chậm trên các tệp lớn

Nó kiểm tra từng ký tự và thay thế các ký tự đặc biệt bằng khoảng trắng. Các phần mềm khác không thực hiện chuyển đổi trong bộ nhớ (ít nhất là không nguyên thủy như notepad). Họ chỉ đưa ra các ký tự đặc biệt khác nhau. Và họ sử dụng các kỹ thuật đệm tiên tiến.


Nhìn vào Notepad.exe (XP 32 bit)

(Tôi giả sử nó vẫn được viết bằng C ++ hoặc ít nhất là sử dụng một trình liên kết tương tự tương tự )

sổ tay

Tôi đang sử dụng công cụ PEiD (đã ngừng phát triển với việc giới thiệu PE + / 64 exes)

Có thể tìm thấy PEiD trong gói thư mục bin của Universal Extractor

Tôi trích xuất notepad. tập tin ex_ từ Windows xp iso rõ ràng. Hãy thử nó. Đó là một trích xuất tập tin taxi sử dụng 7z.

Cảnh báo ! Trình quét vi-rút của bạn có thể phát hiện Universal Extractor / PEiD dưới dạng các công cụ hack hoặc vi-rút. Đừng tin nó đừng tải nó !!


Thông tin thêm về API windows

tín dụng: Jason C

Nó không chỉ là hộp văn bản; Nói chung, WM_SETTEXT không cung cấp tham số nào để chỉ định độ dài chuỗi và các chuỗi luôn được giả định là chấm dứt ở mức null. Bạn luôn có thể tạo một hộp văn bản tùy chỉnh với một thông báo tùy chỉnh chỉ định độ dài chuỗi, nhưng Notepad và hầu hết các chương trình khác thì không. Ngoài ra, hàm SetWindowText cũng không cung cấp tham số độ dài.


1
Có một điều lạ là bạn hiển thị trang thuộc tính cho một tệp thực thi Notepad được gói cùng với một phiên bản Windows XP, nhưng đánh giá theo chủ đề cửa sổ, bạn rõ ràng đang chạy một số phiên bản Windows 8. Điều đó sẽ giải thích tại sao tệp thực thi được liên kết với phiên bản 7.1 của bộ công cụ, đó là những gì họ đã sử dụng để biên dịch Windows XP và các tiện ích liên quan. Phiên bản Windows 8 của Notepad chắc chắn sẽ được biên dịch với phiên bản mới hơn của các công cụ SDK.
Cody Grey

2
Nó không chỉ là hộp văn bản; WM_SETTEXTnói chung không cung cấp tham số nào để chỉ định độ dài chuỗi và các chuỗi luôn được giả định là chấm dứt ở mức null. Bạn luôn có thể tạo một hộp văn bản tùy chỉnh với một thông báo tùy chỉnh chỉ định độ dài chuỗi, nhưng Notepad và hầu hết các chương trình khác thì không.
Jason C

@BhathiyaPerera Bởi vì tôi hài lòng với mức độ công việc mà tôi đã thực hiện bằng cách thêm thông tin trong một nhận xét. Bạn được hoan nghênh cải thiện câu trả lời của bạn với thông tin đó nếu bạn muốn.
Jason C

28

Notepad không bảo tồn tất cả các ký tự đặc biệt / mở rộng chính xác như bản chất của chúng. Tôi không có tài liệu tham khảo cho hành vi này ngay lập tức nhưng đã phát hiện ra đây là trường hợp ví dụ với dòng cuối kiểu UNIX mà Notepad sẽ chuyển đổi thành CRLF và null (0x00) mà nó sẽ bỏ qua. Trong tệp nhị phân như JPG có thể xuất hiện ngẫu nhiên các ký tự mà Notepad không lưu giữ. Hãy thử trải nghiệm với trình soạn thảo nhận biết HEX và nó sẽ hoạt động sau đó. Tôi sẽ cập nhật câu trả lời của mình nếu tôi tìm thấy một tài liệu tham khảo tốt và một khi tôi đã thử trình soạn thảo HEX.

Cập nhật: Tôi đã thử một vài biên tập viên lập trình nổi tiếng nhưng chỉ một trong số họ làm việc ngay lập tức, HxD của Maël Hörz . Tôi chưa bao giờ sử dụng HxD trước đây nhưng tìm thấy nó nhờ vào câu trả lời cho bài viết Stack này, Trình cắm / trình chỉnh sửa hex cho Notepad ++ .

Các trình soạn thảo khác không hoạt động sau vài phút nỗ lực là Notepad ++, Notepad2 và UltraEdit (v17.3, phiên bản cũ hơn). Một vài trong số này có vấn đề với việc sao chép / dán một vài byte đầu tiên, số ma thuật chữ ký tệp JPEG FF D8 FF. Có lẽ họ sẽ làm việc với một chút khó khăn hơn tôi có thời gian hiện tại.


Sublime Text (2/3) tự động mở tệp nhị phân bằng cách hiển thị tệp ở định dạng hex. Ví dụ: bắt đầu tệp JPEG bằng cách chỉ cần nhấp vào "mở": puu.sh/aaAVx/bd08dab46e.png
tomsmeding

3
Trên thực tế, thường xuyên hơn notepad sẽ chuyển đổi LF thành CRLF, nó sẽ rời khỏi cách thức hoạt động của nó và hiển thị văn bản như thể không có ngắt dòng nào cả!
Moshe Katz

6

Bạn đã từng có thể làm điều này với Viết lại trong ngày. Đó là một chương trình tiêu chuẩn trong Windows 3.1 nhưng tôi không thể nhớ nếu Windows 95 bao gồm nó. Viết sẽ cho phép chỉnh sửa an toàn nhị phân bất kỳ tệp nào nó có thể mở (có thể kích thước tệp rất hạn chế). Notepad chắc chắn không an toàn nhị phân (văn bản vẫn giữ nguyên nhưng các byte thực tế của các ký tự không phải văn bản [ví dụ: mã điều khiển] có thể thay đổi), đó là lý do tại sao ví dụ JPG của bạn không hoạt động. Hãy thử lấy một bản sao của Write (và Windows rất cũ) và thử lại lần nữa!

Theo bài viết "Windows Write" của Wikipedia, Write đã được đưa vào Windows NT 3.5. Nó đã được thay thế bởi Wordpad trong Windows 95 trở đi. write.exevẫn còn hiện diện trong thư mục Windows nhưng chỉ đơn giản là một trình bao bọc để mở Wordpad.


5

Tôi nghĩ đó không phải là vấn đề về mã hóa mà còn về bộ ký tự. Định dạng JPG về cơ bản là một luồng byte. Do đó, cho phép các ký tự không in được như NUL, ETX, STX, SOH, DLE, v.v.

Microsoft Notepad không thể hiển thị các ký tự không in được. Nó có thể hiển thị giữ chỗ của một số loại như khoảng trắng cho ký tự null. Vì vậy, mở tệp bằng Notepad không hiển thị nội dung thực tế nhưng nội dung được giải mã bằng mã hóa đã chọn (utf-8, utf-16, v.v.) và được hiển thị bởi một bộ ký tự nhất định (unicode, ascii, v.v.) ngoại trừ không phải ký tự có thể in.

Khi chọn tất cả văn bản được hiển thị và sao chép văn bản vào bảng tạm, bạn chỉ sao chép các ký tự có thể in được bao gồm cả phần giữ chỗ. Do đó, tự động chuyển đổi các ký tự null thành khoảng trắng và bỏ qua hoàn toàn các ký tự không in được khác.

Vì vậy, về cơ bản bạn chỉ mất nội dung làm theo cách này. Nếu bạn sử dụng trình soạn thảo hex thay thế, nó sẽ sao chép toàn bộ nội dung.


Cập nhật: Câu trả lời của Bhathiya Pereras là đúng: https://superuser.com/a/782885/322784 Các ký tự không in được không bị bỏ qua khi sao chép văn bản vào clipboard.


Mỗi tệp là "về cơ bản là một luồng byte".
Jason C

1
@JasonC Tôi sẽ không đồng ý. Trong khi mọi tệp có thể được đọc dưới dạng luồng byte. Các tệp có cấu trúc như các tệp XML không thể đọc được dưới dạng luồng dữ liệu. Nội dung sẽ không có giá trị cho đến khi kết thúc tập tin đã được đọc. Việc cắt giảm một nửa jpg vẫn còn hiệu lực và có thể được hiển thị. Nó chỉ thiếu một nửa hình ảnh.
bắt đầu

Thực sự không có chỗ cho sự bất đồng về điều đó. :) XML là một luồng byte giống như mọi thứ khác và XML (cùng với mã hóa ký tự) định nghĩa một định dạng cho các byte đó. Nó chắc chắn có thể đọc được như một luồng dữ liệu. Mở nó trong một trình soạn thảo hex, ví dụ. Luồng dữ liệu đó chỉ có thể được phân tích cú pháp dưới dạng XML.
Jason C

@JasonC Không thể tranh luận với điều đó thực sự. :) Touché!
bắt đầu

2

Tệp JPEG chứa dữ liệu không phải văn bản ngoại trừ một số trường, về cơ bản, bất kỳ giá trị byte nào trong khoảng từ 0 đến 255 sẽ được tìm thấy, đặc biệt là trong khu vực đại diện cho hình ảnh nén được mã hóa chứa dữ liệu gần như giả ngẫu nhiên.

Nhưng Notepad sẽ coi dữ liệu là văn bản ANSI theo mặc định, do đó, nó sẽ thực hiện nhiều việc khác nhau sẽ thay đổi dữ liệu gốc, như:

  • thay thế byte ánh xạ các ký tự đặc biệt / không xác định / bị cấm vì chúng không có ý nghĩa đối với văn bản ANSI hợp lệ

  • mã hóa lại các ký tự null, kết thúc dòng và kết thúc chuỗi tệp theo các quy ước của Windows / DOS

Điều đó có nghĩa là nếu bạn chỉnh sửa và lưu dữ liệu dưới dạng văn bản, nó sẽ thay đổi jpeg trong trường hợp tốt nhất và làm cho nó không sử dụng được trong trường hợp xấu nhất.


"ANSI" không đúng về mặt kỹ thuật , mặc dù nó thường được hiểu.
Jason C
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.