Öffnete ein JPG-Bild mit dem Editor, fügte den gesamten „Text“ in eine neue Editor-Datei ein, änderte ihn in JPG und öffnete sich nicht mehr. Warum?

82

Dieses Phänomen hat mir Fragen gestellt.

Hier ist das ausführliche Experiment, mein Betriebssystem ist Windows 7 x64 SP1:

  • Ich habe eine Bilddatei (JPG) in TXT geändert, indem ich einfach ihre Erweiterung geändert habe (oder man hat einfach beschlossen, die JPG mit dem Editor zu öffnen, das Gleiche).

Es sollte so aussehen, seltsam aussehende Sequenzen von Texten, und einige von ihnen (sehr selten) sind tatsächlich bedeutungsvoll, wie im Screenshot unten "creator: dg-jpeg v1.0 ..."

Beispiel-JPG-Text

  • Ich habe den Zeilenumbruch deaktiviert und den gesamten Text mit Strg + A ausgewählt (um sicherzustellen, dass nichts übersehen wird)
  • Ich habe den kopierten Text in eine andere leere TXT-Datei eingefügt und als JPG gespeichert und die neue Dateigröße mit der ursprünglichen JPG verglichen. Alle Dateien (das Original-JPG, die konvertierte TXT-Datei und die neu erstellte TXT-Datei) haben die exakt gleiche Größe (in Byte).

Wenn ich versuchte, zu öffnen, sagte Windows "Windows Photo Viewer kann dieses Bild nicht öffnen, da die Datei beschädigt, beschädigt oder zu groß zu sein scheint" .

Ich habe sogar versucht , es zu testen andere Methode verwendet: das JPG mit Notepad geöffnet, schnitt ich ONE bekannt Charakter von einem Ort leicht zu merken (wie das ersten Zeichen der zweiten Zeile) , dann speichern Sie die Datei. Der Betrachter würde natürlich die gleiche Nachricht anzeigen. Dann öffnete ich es erneut und fügte das Zeichen an der EXAKT- Stelle ein (Notepad merkt sich den Ausgangszustand wie Fensterposition, Umbruch, Schriftgröße ... also habe ich keine Probleme, das richtig zu machen).

Und immer noch der gleiche Fehler. Sie können dies versuchen, um auf die Idee zu kommen. Denken Sie daran, ein kleines Bild auszuwählen. Andernfalls verhält sich Notepad wie ein alter, rostiger Mann.

Was könnte die Ursache für dieses Phänomen gewesen sein?

Nguyễn Tuấn Danh
quelle
4
Versuchen Sie es mit dem Befehl fc. Öffne eine cmd-Eingabeaufforderung und mache Folgendes: C:\blah>fc file1 file2 Es ist möglich, dass Dateien dieselbe Größe haben, aber unterschiedlich sind. (Obwohl normalerweise eine zufällige Änderung nicht dazu führt, dass eine Datei dieselbe Größe hat, dies jedoch leicht möglich ist). Der Befehl fc ist für Sie sehr nützlich, wenn Sie untersuchen möchten, was gerade passiert. Sie können auch den Befehl xxd verwenden, der sich in cygwin befindet und auch in vim7 enthalten ist. xxd -p Datei1 Damit wird das Hex einer Datei ausgegeben. Sie können das Hex der beiden Dateien damit und mit fc vergleichen. Oder öffnen Sie das Hex in Notepad und blättern Sie mit Alt-Tab zwischen den beiden Notepad-Fenstern.
Barlop
22
Sie versuchen, eine Binärdatei mit einem einfachen Texteditor wie Notepad zu lesen. Die ANSI-Codierung kann nicht korrekt gelesen und somit konvertiert werden. Wenn Sie es speichern, ist die Datei nicht mehr binär und der Parser kann die Daten in der Datei nicht lesen. (Der Unterschied zwischen dem Speichern von XML-basierten Dateien und dem Speichern von Binärdateien ist ein interessantes Thema.) Wenn Sie dasselbe Experiment mit Notepad ++ ausführen, werden Sie erfolgreich sein.
Woutervs
3
Für die Interessierten: Sie können Bilder in Vim bearbeiten: Der Trick ist jedoch, dass Vim die Datei in das XPM- Format konvertiert, das reines ASCII-Format ist.
Boldewyn
4
Kurz gesagt, Notepad ändert Ihre Datei, bevor es Ihnen angezeigt wird.
Derek 朕 朕 功夫

Antworten:

81

Abhängig von der zum Öffnen der Datei verwendeten Codierung wird möglicherweise ein anderes Verhalten angezeigt. Mit meinem Windows 7-Editor kann eine Datei in ANSI, UTF-8, Unicode oder Unicode-Big-Endian geöffnet werden.

Ich habe dieses Problem mit einem kleinen 2 x 2-Pixel-JPEG-Bild getestet, das mit Gimp erstellt und die Bilddatei mit ANSI-Codierung geöffnet und gespeichert wurde. Wenn ich sowohl das Originalbild als auch das gespeicherte Bild mit einem Hex-Editor öffne, sehe ich, dass alle 00 Sequenzen (zwei Hex-Ziffern, NUL-Steuerzeichen ) in 20 (Leerzeichen) konvertiert wurden.

Wenn Sie im Hex-Editor alle 20 durch 00 ersetzen, wird das Bildformat wiederhergestellt.

Ich habe ein bisschen gegoogelt und keine Referenzen gefunden, die erklären, warum das so ist. Nur ein Verweis auf einen Beitrag, der davor warnt (Google Cache Link, die Seite ist nicht verfügbar).

Wenn Sie die Datei als UTF-8 speichern / öffnen, werden anscheinend immer noch NUL-Zeichen in Leerzeichen konvertiert, die resultierende Dateigröße wird jedoch durch Konvertierungen von Einzelbyte-Zeichen in UTF-8-Mehrbyte-Sequenzen erhöht.

Wenn Sie die Datei als Unicode speichern / öffnen, werden scheinbar immer noch NUL-Zeichen in Leerzeichen konvertiert, aber auch ein Byte am Anfang der Datei, der Stückliste , hinzugefügt .

Zerfleischen
quelle
22
0x00 ist ein Zeichenfolgenabschluss in C-Zeichenfolgen. Sie haben sie möglicherweise ersetzt, da eine Textdatei sie nicht enthalten sollte. Notepad ist ein sehr altes Programm.
Zonder
25
Ich bezweifle, dass notepad.exe eine ausführbare .NET-Datei ist.
Knittl
10
@ Bakuriu AC-Zeichenfolge kann höchstwahrscheinlich in einer Datei vorhanden sein; Ich kann mir zahlreiche Dateiformate vorstellen, die sie enthalten. Die überwiegende Mehrheit der mit Windows-Apps gelieferten Apps ist nativ und nicht .NET. Das heißt, Editor schreibt keine nullterminierten Zeichenfolgen in Dateien.
Carey Gregory
4
@ Bakuriu: Windows-Programme werden normalerweise nicht in .NET geschrieben. Es ist C / C ++ und im Kern nativ. Eine der von Microsoft entwickelten .NET-Anwendungen war Live-Writer, der jetzt eingestellt wird.
Bhathiya-Perera
5
@ SJuan76 Huh? C ++ definiert keinen Datentyp namens byte. Vielleicht denken Sie an eine andere Sprache. Und die Anwendungsentwickler können mit Binärdaten umgehen, wie sie es für richtig halten, einschließlich der Verwendung von C-Zeichenfolgen, wenn sie dies wünschen. Wie ich bereits sagte, kann ich mir zahlreiche Binärdateiformate vorstellen, die C-Zeichenfolgen enthalten.
Carey Gregory
37

Warum es fehlschlägt:

Notepad erstellt Leerzeichen (ASCII code 32)für Zeichen wie NUL, (ASCII code 0) da das Textfeld der Windows-API nur nullterminiertes char * ASCIIZ (Zeichenarray, Zeiger) zulässt . Es wird beim ersten NUL abgeschnitten.

Dies liegt daran, dass die Windows-API zumeist in C- Sprache geschrieben ist und Zeichenfolgen mit NULL-Abschluss eine der allgemeinen Funktionen sind. Auch wenn moderne Windows- und Unicode-Versionen als identisch angesehen werden, treten nullterminierte Zeichenfolgen auf. Ersetzen Sie sie einfach durch Leerzeichen, damit Sie die gesamte Datei anzeigen können.

Wenn Sie die Datei speichern, ist sie beschädigt.

wikipedia-null terminierte Strings


Wie man weiter forscht:

Sie können einen unvergleichlichen Vergleich verwenden (kommerziell, Testversion) , um den Charakterersatzeffekt zu sehen. Siehe auch andere binäre Vergleichstools .

Hex Vergleich

Anmerkung : (20) 16 = (32) 10


Grund für Notizblock wirkt sich langsam auf große Dateien aus

Es prüft jedes Zeichen und ersetzt Sonderzeichen durch Leerzeichen. Andere Software führt keine In-Memory-Konvertierungen durch (zumindest nicht primitiv als Editor). Sie rendern nur Sonderzeichen anders. Und sie verwenden fortschrittliche Puffertechniken.


Suchen in Notepad.exe (XP 32 Bit)

(Ich gehe mal davon aus, dass es noch in C ++ geschrieben ist oder benutze zumindest einen vergleichbaren Linker )

Notizblock

Ich benutze das PEiD- Tool (das die Entwicklung mit der Einführung von PE + / 64-Exes gestoppt hat)

PEiD befindet sich gebündelt im bin-Ordner von Universal Extractor

Ich zog den Notizblock heraus. ex_ Datei von der Windows XP ISO offensichtlich. Versuch es. Es ist ein Cab-Dateiextrakt mit 7z.

Warnung ! Ihr Virenscanner erkennt Universal Extractor / PEiD möglicherweise als Hack-Tools oder Viren. Vertraue nicht es lade es nicht herunter !!


Weitere Informationen zur Windows-API

Credits: Jason C

Es ist nicht nur das Textfeld; WM_SETTEXT bietet im Allgemeinen keinen Parameter zum Angeben der Zeichenfolgenlänge, und es wird immer davon ausgegangen, dass Zeichenfolgen bei Null enden. Sie könnten jederzeit ein benutzerdefiniertes Textfeld mit einer benutzerdefinierten Nachricht erstellen, in der die Zeichenfolgenlänge angegeben ist, aber Notepad und die meisten anderen Programme tun dies vernünftigerweise nicht. Auch die Funktion SetWindowText bietet keinen Längenparameter .

Bhathiya-Perera
quelle
1
Es ist ein wenig seltsam, dass Sie das Eigenschaftenblatt für eine ausführbare Datei für Notepad anzeigen, die mit einer Version von Windows XP gebündelt ist, aber nach dem Fensterthema eine Version von Windows 8 ausführen. Dies würde erklären, warum die ausführbare Datei mit verknüpft war Toolset-Version 7.1 - mit dieser Version wurden Windows XP und die zugehörigen Dienstprogramme kompiliert. Die Windows 8-Version von Notepad wird zweifellos mit einer neueren Version der SDK-Tools kompiliert.
Cody Grey
2
Es ist nicht nur das Textfeld; WM_SETTEXTIm Allgemeinen wird kein Parameter zum Angeben der Zeichenfolgenlänge bereitgestellt, und es wird immer davon ausgegangen, dass Zeichenfolgen bei null enden. Sie könnten jederzeit ein benutzerdefiniertes Textfeld mit einer benutzerdefinierten Nachricht erstellen, in der die Zeichenfolgenlänge angegeben ist, aber Notepad und die meisten anderen Programme tun dies vernünftigerweise nicht.
Jason C
@BhathiyaPerera Weil ich mit der Arbeit zufrieden bin, die ich geleistet habe, indem ich Informationen in einen Kommentar eingefügt habe. Sie können gerne Ihre Antwort mit diesen Informationen verbessern, wenn Sie möchten.
Jason C
28

Notepad behält nicht alle Sonderzeichen / erweiterten Zeichen so bei, wie sie sind. Ich habe keine Referenz für dieses Verhalten sofort zur Hand, aber ich habe festgestellt, dass dies beispielsweise bei UNIX-artigen Zeilenende-LF der Fall ist, die der Editor in CRLF und null (0x00) konvertiert, die er ignoriert. In einer Binärdatei wie JPG können zufällige Zeichen vorkommen, die von Notepad nicht beibehalten werden. Versuchen Sie Ihr Experiment mit einem HEX-fähigen Editor und es sollte dann funktionieren. Ich werde meine Antwort aktualisieren, wenn ich eine gute Referenz gefunden und einen HEX-Editor getestet habe.

Update: Ich habe einige bekannte Programmierer-Editoren ausprobiert, aber nur einer von ihnen hat auf Anhieb funktioniert, HxD von Maël Hörz . Ich habe HxD noch nie benutzt, fand es aber dank einer Antwort auf diesen Stack-Artikel, Ein Hex-Viewer / Editor-Plugin für Notepad ++ .

Die anderen Editoren, die nach wenigen Minuten nicht funktionierten, waren Notepad ++, Notepad2 und UltraEdit (v17.3, ältere Version). Einige von ihnen hatten Probleme mit dem Kopieren / Einfügen der ersten Bytes, der magischen Signaturnummer FF D8 FF der JPEG- Datei . Vielleicht würden sie ein bisschen fummeliger arbeiten, als ich momentan Zeit habe.

JohnC
quelle
Sublime Text (2/3) öffnet automatisch eine Binärdatei, indem es sie im Hex-Format anzeigt. Zum Beispiel der Start einer JPEG-Datei durch einfaches
tomsmeding
3
Tatsächlich wird LF häufiger in CRLF konvertiert als in notepad, es wird das LF so belassen, wie es ist, und der Text wird so angezeigt, als ob überhaupt kein Zeilenumbruch stattgefunden hätte!
Moshe Katz
6

Früher war dies mit Write back in the day möglich. Es war ein Standardprogramm in Windows 3.1, aber ich kann mich nicht erinnern, ob Windows 95 es enthielt. Write würde eine binär sichere Bearbeitung aller Dateien ermöglichen, die es öffnen könnte (wahrscheinlich sehr begrenzte Dateigröße). Notepad ist definitiv nicht binär sicher (der Text bleibt derselbe, aber die tatsächlichen Bytes von Nicht-Text-Zeichen [z. B. Steuercodes] können sich ändern), weshalb Ihr JPG-Beispiel nicht funktioniert. Holen Sie sich eine Kopie von Write (und einem sehr alten Windows) und versuchen Sie es erneut.

Laut Wikipedia-Artikel "Windows Write" war Write bis Windows NT 3.5 enthalten. Es wurde ab Windows 95 durch Wordpad ersetzt. write.exewar noch im Windows-Verzeichnis vorhanden, war aber nur ein Wrapper zum Öffnen von Wordpad.

CJ Dennis
quelle
5

Ich denke, es ist nicht so sehr ein Problem der Codierung, sondern auch des Zeichensatzes. Das JPG-Format ist im Grunde ein Byte-Stream. Dies ermöglicht nicht druckbare Zeichen wie NUL, ETX, STX, SOH, DLE usw.

Microsoft Editor kann diese nicht druckbaren Zeichen nicht anzeigen. Es kann Platzhalter wie ein Leerzeichen für ein Nullzeichen anzeigen. Das Öffnen der Datei mit Notepad zeigt also nicht den tatsächlichen Inhalt an, sondern den Inhalt, der durch die ausgewählte Codierung (utf-8, utf-16 usw.) decodiert und durch einen bestimmten Zeichensatz (Unicode, ASCII usw.) angezeigt wird, mit Ausnahme der nicht druckbare Zeichen.

Wenn Sie den gesamten angezeigten Text auswählen und in die Zwischenablage kopieren, kopieren Sie nur die druckbaren Zeichen einschließlich der Platzhalter. Konvertiert daher automatisch Nullzeichen in Leerzeichen und ignoriert andere nicht druckbare Zeichen vollständig.

Sie verlieren also im Grunde nur den Inhalt, wenn Sie dies auf diese Weise tun. Wenn Sie stattdessen einen Hex-Editor verwenden, wird der gesamte Inhalt vollständig kopiert.


Update: Bhathiya Pereras Antwort ist richtig: https://superuser.com/a/782885/322784 Nicht druckbare Zeichen werden beim Kopieren von Text in die Zwischenablage nicht ignoriert.

sbecker
quelle
Jede Datei ist "im Grunde genommen ein Bytestream".
Jason C
1
@ JasonC Ich würde nicht zustimmen. Dabei kann jede Datei als Byte-Stream gelesen werden. Strukturierte Dateien wie XML-Dateien können nicht als Datenstrom gelesen werden. Der Inhalt ist erst gültig, wenn das Ende der Datei gelesen wurde. Ein Schnitt in halbes JPG ist weiterhin gültig und kann angezeigt werden. Es fehlt nur die Hälfte des Bildes.
sbecker
Da gibt es nicht wirklich Raum für Meinungsverschiedenheiten. :) XML ist ein Strom von Bytes wie alles andere, und XML (zusammen mit der Zeichenkodierung) definiert ein Format für diese Bytes. Es ist sicherlich als Datenstrom lesbar. Öffnen Sie es beispielsweise in einem Hex-Editor. Dieser Datenstrom kann einfach als XML analysiert werden.
Jason C
@JasonC Kann damit eigentlich nicht streiten. :) Touché!
Sebecker
2

Die JPEG-Datei enthält mit Ausnahme einiger Felder keine Textdaten. Grundsätzlich werden Byte-Werte zwischen 0 und 255 gefunden, insbesondere in dem Bereich, der das codierte komprimierte Bild darstellt, das nahezu pseudozufällige Daten enthält.

In Notepad werden die Daten jedoch standardmäßig als ANSI-Text behandelt, sodass verschiedene Aktionen ausgeführt werden, die die ursprünglichen Daten ändern:

  • Ersetzen Sie Bytes, die Sonder- / undefinierte / verbotene Zeichen zuordnen, da dies für einen gültigen ANSI-Text keinen Sinn ergibt

  • Kodieren Sie Nullzeichen, Zeilenende und Dateiende neu nach Windows / DOS-Konventionen

Das heißt, wenn Sie die Daten bearbeiten und als Text speichern, wird das JPEG im besten Fall geändert und im schlechtesten Fall unbrauchbar.

Würfel9
quelle
"ANSI" ist technisch nicht korrekt , obwohl es allgemein verstanden wird.
Jason C