Ha aperto un'immagine JPG con Blocco note, incollato tutto il "testo" in un nuovo file di Blocco note, modificato in .JPG e non si apre più. Perché?


82

Questo fenomeno mi ha lasciato domande da porre.

Ecco l'esperimento dettagliato, il mio sistema operativo è Windows 7 x64 SP1:

  • Ho cambiato un file di immagine (JPG) in TXT semplicemente cambiando la sua estensione (o si potrebbe semplicemente scegliere di aprire il JPG con il blocco note, stessa cosa)

Dovrebbe assomigliare a questo, sequenze di testi dall'aspetto strano, e alcuni di essi (molto rari) sono in realtà significativi, come nello screenshot qui sotto "creatore: dg-jpeg v1.0 ..."

Testo di esempio JPG

  • Ho disabilitato il wrapping e selezionato tutto il testo usando Ctrl + A (per assicurarmi che non ci sia mancato nulla)
  • Ho incollato il testo copiato in un altro file TXT vuoto e l'ho salvato come JPG, ho confrontato le dimensioni del nuovo file con il JPG originale. Tutti loro (l'originale JPG, il file convertito TXT e il file TXT di nuova creazione) sono del esatto stessa dimensione, in byte.

Quando ho provato ad aprire, Windows diceva "Windows Photo Viewer non può aprire questa immagine perché il file sembra essere danneggiato, corrotto o troppo grande" .

Ho anche provato a provarlo usando un altro metodo: ho aperto JPG con il blocco note, ho tagliato UN personaggio conosciuto da una posizione facile da ricordare (come il primo carattere della seconda riga), quindi ho salvato il file. Naturalmente il visualizzatore visualizzerebbe lo stesso messaggio. Quindi l'ho aperto di nuovo e ho incollato il personaggio nella posizione ESATTA (Blocco note ricorda il suo stato di uscita come la posizione di Windows, il wrapping, la dimensione dei caratteri ... quindi non ho problemi a farlo bene)

E ancora lo stesso errore. Puoi provare questo per avere l'idea, ricordati di scegliere una piccola immagine altrimenti Blocco note si comporterà come un vecchio uomo arrugginito.

Quale potrebbe essere stata la causa di questo fenomeno?


4
Prova il comando fc. apri un prompt cmd e fai- C:\blah>fc file1 file2 È possibile che i file abbiano le stesse dimensioni ma siano diversi. (sebbene di solito alcune modifiche casuali non tendano a lasciare un file della stessa dimensione ma potrebbe facilmente). Il comando fc ti sarà molto utile per indagare su ciò che sta accadendo. Puoi anche usare il comando xxd, questo è in cygwin e viene fornito anche con vim7. xxd -p file1 Questo scaricherà l'esagono di un file. Puoi confrontare l'esagono dei due file con quello e fc. O anche aprire l'esagono nel blocco note e scorrere tra le due finestre del blocco note con alt-tab.
barlop

22
Stai provando a leggere un file binario con un semplice editor di testo come Blocco note. Non sarà in grado di leggere correttamente la codifica ANSI e quindi la convertirà. Quando lo salvi, il file non sarà più binario e quindi il parser non può leggere i dati all'interno del file. (Cercare la differenza tra il salvataggio di file basato su XML e il salvataggio di file binario è un argomento interessante.) Se si provasse lo stesso esperimento con Notepad ++, si riuscirà in quello che si stava provando.
woutervs


3
Per gli interessati: è possibile modificare le immagini in Vim: Tuttavia, il trucco è che Vim converte il file nel formato XPM , che è semplicemente ASCII.
Boldewyn,

4
Per farla breve, Blocco note modifica il file prima di visualizzarlo.
Derek 朕 會 功夫

Risposte:


81

A seconda della codifica utilizzata per aprire il file, è possibile che si verifichino comportamenti diversi. Il mio blocco note di Windows 7 consente di aprire un file in big endian ANSI, UTF-8, Unicode o Unicode.

Ho provato questo problema con una piccola immagine jpeg da 2x2 pixel creata con gimp e aprendo e salvando il file di immagine con codifica ANSI. Aprendo sia l'immagine originale che quella salvata con un editor esadecimale, vedo che tutte le 00 sequenze (due cifre esadecimali, carattere di controllo NUL ) sono state convertite in 20 (carattere spazio).

Sostituendo nell'editor esadecimale tutti i 20 per 00 ripristina il formato dell'immagine.

Ho cercato su Google un po 'e non ho trovato riferimenti che spiegano perché lo fa. Solo un riferimento a un post che lo avvisa (link cache di Google, la pagina non è disponibile).

Se si salva / apre il file come UTF-8 sembra che converta ancora i caratteri NUL in spazi ma aumenta anche le dimensioni del file risultante a causa delle conversioni da caratteri a byte singolo in sequenze multi-byte UTF-8.

Se salvi / apri il file come Unicode sembra che converta ancora i caratteri NUL in spazi ma aggiunge anche un byte all'inizio del file, la distinta base .


22
0x00 è un terminatore di stringa in stringhe C. Potrebbero averli sostituiti poiché un file di testo non dovrebbe contenerli. Notepad è un programma molto vecchio.
Zonder,

25
Dubito che notepad.exe sia un eseguibile .NET.
Knittl

10
La stringa AC @Bakuriu può sicuramente esistere in un file; Posso pensare a numerosi formati di file che li contengono. E la stragrande maggioranza delle app fornite con le app di Windows sono native, non .NET. Detto questo, il blocco note non scrive stringhe con terminazione null nei file.
Carey Gregory,

4
@Bakuriu: i programmi Windows di solito non sono scritti in .Net. È C / C ++ e nativo al centro. Una delle applicazioni .Net sviluppate da Microsoft era Live Writer che ora è fuori produzione.
Bhathiya-Perera,

5
@ SJuan76 Huh? C ++ non definisce un tipo di dati denominato byte. Forse stai pensando a un'altra lingua. E gli sviluppatori di applicazioni possono gestire i dati binari nel modo che ritengono opportuno, incluso l'uso delle stringhe C, se lo desiderano. Come ho detto prima, posso pensare a numerosi formati di file binari che contengono stringhe C.
Carey Gregory,

37

Perché fallisce:

Blocco note crea spazi (ASCII code 32)per caratteri come NUL (ASCII code 0) perché la casella di testo dell'API di Windows consente solo char * ASCIIZ con terminazione null (array di caratteri, puntatore). Viene tagliato al primo NUL.

Ciò accade perché l' API di Windows è per lo più scritta in linguaggio C e le stringhe con terminazione null sono una delle funzionalità comuni. Anche quando Windows moderno e Unicode sono considerati stringhe con terminazione nulla uguale. Quindi il blocco note semplicemente li sostituisce con spazio in modo da poter visualizzare il file completo.

Quindi quando si salva il file è danneggiato.

stringhe terminate wikipedia-null


Come fare ulteriori ricerche:

Puoi usare un comparatore simile a quello del confronto (commerciale, di prova) per vedere l'effetto di sostituzione del personaggio. vedere anche altri strumenti di confronto binario .

confronto esadecimale

Nota : (20) 16 = (32) 10


Il motivo del blocco note agisce lentamente su file di grandi dimensioni

Controlla ogni personaggio e sostituisce i caratteri speciali con spazi. Altri software non eseguono conversioni in memoria (almeno non primitive come blocco note). Rendono semplicemente i caratteri speciali in modo diverso. E usano tecniche di buffering avanzate.


Esaminare Notepad.exe (XP 32 bit)

(Suppongo che sia ancora scritto in C ++ o almeno usi un linker comparativamente simile )

bloc notes

Sto usando lo strumento PEiD (che ha interrotto lo sviluppo con l'introduzione di PE + / 64 exes)

PEiD può essere trovato in bundle nella cartella bin di Universal Extractor

Ho estratto il blocco note. file ex_ dall'ISO di Windows XP ovviamente. Provalo. È un estratto di file cab che utilizza 7z.

Avvertimento ! Lo scanner antivirus potrebbe rilevare Universal Extractor / PEiD come strumenti di hacking o virus. Non fidarti, non scaricarlo !!


Ulteriori informazioni sull'API di Windows

crediti: Jason C

Non è solo la casella di testo; WM_SETTEXT in generale non fornisce alcun parametro per specificare la lunghezza della stringa e si presume che le stringhe terminino sempre su null. È sempre possibile creare una casella di testo personalizzata con un messaggio personalizzato che specifica la lunghezza della stringa, ma Notepad e la maggior parte degli altri programmi ragionevolmente no. Anche la funzione SetWindowText non fornisce un parametro di lunghezza.


1
È un po 'strano che tu mostri la finestra delle proprietà di un eseguibile di Blocco note in bundle con una versione di Windows XP, ma a giudicare dal tema della finestra, stai chiaramente eseguendo una versione di Windows 8. Ciò spiegherebbe perché l'eseguibile era collegato con versione 7.1 del set di strumenti: è quello che hanno usato per compilare Windows XP e le utilità associate. La versione di Notepad per Windows 8 verrà senza dubbio compilata con una versione più recente degli strumenti SDK.
Cody Gray,

2
Non è solo la casella di testo; WM_SETTEXTin generale non fornisce alcun parametro per specificare la lunghezza della stringa e si presume sempre che le stringhe terminino con un valore nullo. È sempre possibile creare una casella di testo personalizzata con un messaggio personalizzato che specifica la lunghezza della stringa, ma Notepad e la maggior parte degli altri programmi ragionevolmente no.
Jason C,

@BhathiyaPerera Perché sono soddisfatto del livello di lavoro che ho svolto aggiungendo informazioni in un commento. Se lo desideri, puoi migliorare la tua risposta con tali informazioni.
Jason C,

28

Blocco note non conserva tutti i caratteri speciali / estesi esattamente come sono. Non ho un riferimento per questo comportamento immediatamente a portata di mano, ma ho trovato che questo è il caso, ad esempio, con la fine della linea LF in stile UNIX che il Blocco note convertirà in CRLF e null (0x00) che ignorerà. In un file binario come un JPG è probabile che si verifichino occorrenze casuali dei caratteri che Notepad non conserva. Prova il tuo esperimento con un editor compatibile con HEX e dovrebbe funzionare allora. Aggiornerò la mia risposta se trovo un buon riferimento e dopo aver testato un editor HEX.

Aggiornamento: ho provato alcuni noti editor di programmatori, ma solo uno di loro ha funzionato subito, HxD di Maël Hörz . Non avevo mai usato HxD prima, ma l'ho trovato grazie a una risposta a questo articolo Stack, un plug-in hex viewer / editor per Notepad ++ .

Gli altri editor che non funzionavano dopo alcuni minuti erano Notepad ++, Notepad2 e UltraEdit (v17.3, versione precedente). Un paio di questi hanno avuto problemi con la copia / incolla dei primi pochi byte, il numero magico della firma del file JPEG FF D8 FF. Forse avrebbero lavorato con un po 'più di confusione di quanto non abbia tempo per ora.


Sublime Text (2/3) apre automaticamente un file binario mostrandolo in formato esadecimale. Ad esempio, l'inizio del file JPEG semplicemente facendo clic su "apri": puu.sh/aaAVx/bd08dab46e.png
tomsmeding

3
In realtà, più spesso che il blocco note convertirà LF in CRLF, lascerà l'LF così com'è e visualizzerà il testo come se non ci fosse alcuna interruzione di riga!
Moshe Katz,

6

Un tempo eri in grado di farlo con Write back in the day. Era un programma standard in Windows 3.1 ma non ricordo se Windows 95 lo includesse. Scrivere consentirebbe la modifica binaria sicura di qualsiasi file che potrebbe aprire (probabilmente una dimensione del file molto limitata). Notepad non è sicuramente binario sicuro (il testo rimane lo stesso ma i byte effettivi di caratteri non testuali [ad es. Codici di controllo] possono cambiare), motivo per cui il tuo esempio JPG non funziona. Prova a ottenere una copia di Write (e Windows molto vecchio) e riprova l'esperimento!

Secondo l'articolo "Windows Write" di Wikipedia, Write è stato incluso fino a Windows NT 3.5. È stato sostituito da Wordpad in Windows 95 in poi. write.exeera ancora presente nella directory di Windows ma era semplicemente un wrapper per l'apertura di Wordpad.


5

Penso che non sia tanto un problema di codifica ma anche di set di caratteri. Il formato JPG è sostanzialmente un flusso di byte. Consentendo così caratteri non stampabili come NUL, ETX, STX, SOH, DLE, ecc.

Blocco note di Microsoft non può visualizzare quei caratteri non stampabili. Può visualizzare segnaposto di qualche tipo come uno spazio per un carattere null. Quindi l'apertura del file con Blocco note non mostra il contenuto effettivo ma il contenuto decodificato dalla codifica selezionata (utf-8, utf-16, ecc.) E visualizzato da un determinato set di caratteri (unicode, ascii, ecc.) Escluso il non- personaggi stampabili.

Quando si seleziona tutto il testo visualizzato e si copia il testo negli Appunti, si copiano solo i caratteri stampabili inclusi i segnaposto. Pertanto, la conversione automatica di caratteri null in spazi e ignorando completamente altri caratteri non stampabili.

Quindi in pratica perdi semplicemente i contenuti facendolo in questo modo. Se invece usi un editor esadecimale, copierà tutto il contenuto.


Aggiornamento: la risposta di Bhathiya Pereras è corretta: https://superuser.com/a/782885/322784 I caratteri non stampabili non vengono ignorati quando si copia il testo negli Appunti.


Ogni file è "sostanzialmente un flusso di byte".
Jason C,

1
@JasonC Non sarei d'accordo. Mentre ogni file può essere letto come un flusso di byte. I file strutturati come i file XML non sono leggibili come flusso di dati. Il contenuto non sarebbe valido fino alla fine della lettura del file. Un taglio in mezzo jpg è ancora valido e può essere visualizzato. Manca solo metà dell'immagine.
sbecker

Non c'è davvero spazio per il disaccordo su questo. :) XML è un flusso di byte come qualsiasi altra cosa e XML (insieme alla codifica dei caratteri) definisce un formato per tali byte. È certamente leggibile come un flusso di dati. Aprilo in un editor esadecimale, ad esempio. Quel flusso di dati sembra essere semplicemente analizzabile come XML.
Jason C,

@JasonC In realtà non posso discutere. :) Touché!
sbecker

2

Il file JPEG contiene dati non testuali ad eccezione di alcuni campi, in pratica verranno trovati valori di byte compresi tra 0 e 255, specialmente nell'area che rappresenta l'immagine compressa codificata che contiene dati quasi pseudocasuali.

Ma Blocco note tratta i dati come testo ANSI per impostazione predefinita, quindi farà varie cose che altereranno i dati originali, come:

  • sostituire i byte che mappano caratteri speciali / non definiti / vietati in quanto non hanno senso per un testo ANSI valido

  • ricodificare i caratteri null, la fine della riga e la fine delle sequenze di file in convenzioni Windows / DOS

Ciò significa che se modifichi e salvi i dati come testo cambierà il jpeg nel migliore dei casi e lo renderà inutilizzabile nel peggiore dei casi.


"ANSI" non è tecnicamente corretto , sebbene sia comunemente compreso.
Jason C,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.