Come sono noti i tipi di file se non dal suffisso del file?


55

Vorrei sapere come sono noti i tipi di file se i nomi dei file non hanno suffissi.

Ad esempio, un file denominato myfilepotrebbe essere binario o di testo per iniziare, come fa il sistema a sapere se il file è binario o di testo?


3
Solo un commento, il resto delle risposte copre tutto. Al giorno d'oggi può accadere che con impostazioni locali errate o vecchi eseguibili, alcuni file utf-8 possano essere erroneamente rilevati come dati binari a causa di byte non ascii.
Orione,

19
Al sistema non importa. Ad alcune applicazioni potrebbe interessare, ma ognuna ha i propri modi di gestirla.
jwodder,

2
Si noti che anche per file regolari (non file di dispositivo, socket di dominio unix, named pipe, ecc.) "Tipo di file" può significare due cose diverse: (1) Un particolare formato di file (".docx", XML, formato di testo MS-DOS , RTF, record a lunghezza fissa, l'elenco potrebbe essere molto lungo) o (2) Un file che una particolare app sa gestire (".xlsx" o ".doc" o qualsiasi altra cosa, si sovrappone al tipo di formato) . Vale la pena tenere presente questa distinzione quando si parla di "tipo di file".
Bruce Ediger,

@jwodder Il sistema se ne frega. È il sistema che si lamenta che non è possibile eseguire un file non eseguibile quando si tenta di farlo, non quelle applicazioni!
Lister

1
@MrLister Vero, ma eseguibile / non eseguibile non ha nulla a che fare con 'extension'.
user2338816

Risposte:


84

L' fileutilità determina il tipo di file in 3 modi:

Innanzitutto i test del filesystem : all'interno di questi test viene richiamata una delle chiamate di sistema della famiglia stat sul file. Ciò restituisce i diversi tipi di file unix : file normale, directory, collegamento, dispositivo a caratteri, dispositivo a blocchi, pipe o socket. A seconda di ciò, vengono eseguiti i test di magia.

I test di magia sono un po 'più complessi. I tipi di file sono indovinati da un database di modelli chiamato file magico . Alcuni tipi di file possono essere determinati leggendo un bit o un numero in una determinata posizione all'interno del file (ad esempio i binari). Il file magico contiene " numeri magici " per verificare se il file contiene o meno e quali informazioni di testo devono essere stampate. Quei " numeri magici " possono essere 1-4Byte valori, stringhe, date o persino espressioni regolari. Con ulteriori test è possibile trovare ulteriori informazioni. Nel caso di un eseguibile, ulteriori informazioni sarebbero se sono dinamicamente collegate o meno, eliminateo no o l'architettura. A volte devono passare più test prima che il tipo di file possa essere veramente identificato. Ma comunque, non importa quanti test vengono eseguiti, è sempre solo una buona ipotesi .

Ecco i primi 8 byte in un file di alcuni tipi di file comuni che possono aiutarci a farci un'idea di come possono apparire questi numeri magici:

             Hexadecimal          ASCII
PNG   89 50 4E 47|0D 0A 1A 0A   ‰PNG|....
JPG   FF D8 FF E1|1D 16 45 78   ÿØÿá|..Ex
JPG   FF D8 FF E0|00 10 4A 46   ÿØÿà|..JF
ZIP   50 4B 03 04|0A 00 00 00   PK..|....
PDF   25 50 44 46|2D 31 2E 35   %PDF|-1.5

Se il tipo di file non può essere trovato su test magici, il file sembra essere un file di testo e filecerca la codifica del contenuto. La codifica si distingue per i diversi intervalli e sequenze di byte che costituiscono il testo stampabile in ciascun set.

Vengono inoltre studiate le interruzioni di riga, a seconda dei loro valori esadecimali:

  • 0A( \n) classifica un file terminato Un * x / Linux / BSD / OSX
  • 0D 0A( \r\n) sono file dai sistemi operativi Microsoft
  • 0D( \r) sarebbe Mac OS fino alla versione 9
  • 15( \025) sarebbe IBM AIX

Ora iniziano i test linguistici . Se sembra essere un file di testo, il file viene cercato per stringhe particolari per scoprire quale lingua contiene (C, Perl, Bash). Alcuni linguaggi di script possono anche essere identificati su hashbang ( #!/bin/interpreter) nella prima riga dello script.

Se nulla si applica al file, il tipo di file non può essere determinato e filestampa semplicemente "dati".

Quindi, vedi che non c'è bisogno di un suffisso. Un suffisso comunque potrebbe confondere, se impostato errato.


4
C'è anche il database MIME condiviso di freedesktop.org, utilizzato essenzialmente da tutte le applicazioni X11. Questo concetto è simile a quello che file(1)fa, ma con un'implementazione (molto) diversa.
lcd047,

4
Si noti che il risultato di questo processo è fondamentalmente un'ipotesi e non dovrebbe essere invocato per qualcosa di importante. (Funzionalità utili, come decidere con quale programma predefinito aprire il file, vanno bene)
user253751

Quindi, se aggiungo% PNG nella parte superiore di un file di testo, verrà visualizzato come un file png. Giusto??
saga,

@saga Se ottieni la codifica corretta e se metti un segno per mille anziché un segno per cento, allora: forse. Potrebbero esserci ulteriori test.
Bananguin,

19

Spesso non importa. Basta passarlo a un programma e o lo interpreta o no. Potrebbe non essere utile aprire un file .jpg in un editor di testo, ma non ti viene impedito di farlo. L'estensione, come il resto del nome del file, è per comodità organizzativa degli umani.

Potrebbe anche essere possibile costruire file che possono essere validamente interpretati in più modi. Poiché il formato di file ZIP iniziale ha un'intestazione alla fine del file , è possibile anteporre altre cose in primo piano e verrà comunque caricato come file ZIP. Questo è comunemente usato per creare file zip autoestraenti.


4
Per quanto riguarda l'ultimo paragrafo: Funky File Formats è un discorso interessante sull'argomento, che presenta ad esempio un jpeg che è anche un programma java hello world, dopo che AES lo ha crittografato diventa un PNG, o dopo la decrittazione 3DES diventa un PDF e altro ( tutti con contenuti "interessanti", cioè non solo con rumore bianco o artefatti)
Hagen von Eitzen,

14

Tali informazioni si trovano comunemente nell'intestazione del file. Il filecomando analizza la destinazione e fornisce informazioni sul file. Molte informazioni derivano spesso dalle intestazioni dei file che sono spesso volte i primi pochi byte di un file (vedi sotto). Le intestazioni vengono utilizzate dal sistema per capire come gestire i file. #!/bin/bashall'inizio di un file dice al sistema di usare la shell bash per interpretare il seguente script. ELFdice al sistema che si tratta di un eseguibile ELF.

[~] root@www # file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

[~] root@www # file /etc/passwd
/etc/passwd: ASCII text

Esempi di intestazione del file:

[root@server4 ~]# xxd old_sm_logo.png | head -5
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
0000010: 0000 0134 0000 006f 0806 0000 0062 bf3c  ...4...o.....b.<

[root@server4 ~]# xxd /bin/ls | head -5
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 3e00 0100 0000 a024 4000 0000 0000  ..>......$@.....

[root@server4 proj]# xxd resizer.sh | head -5
0000000: 2321 2f62 696e 2f62 6173 680a 5b20 2d7a  #!/bin/bash.[ -z
0000010: 2022 2431 2220 5d20 2626 2065 6368 6f20   "$1" ] && echo

3
Questo è piuttosto fuorviante. I file Unix non hanno di per sé un'intestazione. Il filecomando tenta di indovinare dal contenuto del file come probabilmente il file è destinato a essere utilizzato. Non è infallibile.
Nate Eldredge,

Hai ragione nel spiegare il comportamento di file. Effettua infatti un'analisi del file. Tuttavia, la maggior parte dei tipi di file sono identificati da una sorta di intestazione. 0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............è un'intestazione di un eseguibile ELF (primi pochi byte di / bin / ls). Allo stesso modo #!/bin/bashnella parte superiore di un file ASCII lo identificherebbe come uno script di shell. Un altro esempio: 0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR(un'immagine .png)
h3rrmiller,

2
Ma la tua risposta fa sembrare che un'intestazione sia una caratteristica intrinseca di un file Unix. I file di testo, ad esempio, non hanno una tale intestazione; qualcuno come l'OP probabilmente considererebbe un file sorgente C e un file sorgente Java con diversi "tipi di file", ma non esiste un'intestazione per distinguerli. Direi che "tipo di file" non è nemmeno un concetto significativo sotto Unix; il sistema operativo fornisce solo un file system e spetta a ciascuna applicazione decidere cosa significano i contenuti di un determinato file.
Nate Eldredge,

Sono d'accordo. Stavo cercando di rispondere il più semplicemente possibile senza andare in troppe buche di coniglio.
h3rrmiller,

7

La prima cosa da controllare è il tipo di file codificato che viene riconosciuto dal kernel. Questi sono i tipi di file come directory, file con caratteri speciali, file con blocchi speciali, file con pipe speciali, socket e collegamento simbolico. Questa informazione proviene dall'inode del file. Se il file è un file semplice, la successiva serie di informazioni proviene dai primi 256 byte cercando i pattern. Pertanto, i file di testo e il codice sorgente C vengono riconosciuti esaminando tali byte. Inoltre, le utility cercano anche un numero magico utilizzato per testare e convalidare il tipo di file. È possibile aggiungere i propri tipi di file da riconoscere aggiungendo le informazioni al file /etc/magic. Fare riferimento alla pagina man per magic(5)vedere il formato del file magico.

Nell'implementazione precedente (ad esempio Solaris), il file /etc/magicelencava la maggior parte dei tipi di file riconosciuti.


4

Il filecomando applica alcune euristiche dall'ispezione (parti di) del file e l'esecuzione di un'ipotesi qualificata. Oltre a ciò ci sono alcuni casi speciali in cui è possibile ottenere ulteriori informazioni; come #!all'inizio di un file di testo, un BoM (contrassegno dell'ordine dei byte) o byte di intestazione specifici di formati di file eseguibili. I #!segni binari e nei file eseguibili vengono utilizzati dal sistema per distinguerli.


4

Il sistema non sa se un file è binario o di testo. In tutti i sistemi operativi (AFAIK) di tipo Unix, fopen(path, "rb")è esattamente lo stesso di fopen(path "r")- il bnon ha alcun effetto. È accettato perché lo standard C deve essere portabile su alcuni altri sistemi operativi che fanno una tale distinzione.


0

Direi che "tipo di file" non è nemmeno un concetto significativo sotto Unix;

Ai vecchi tempi dei commutatori mainframe il loro sistema operativo supportava diversi tipi di file, tra cui sequenziale e indice-sequenziale. I moderni sistemi operativi (Un * x e probabilmente Windows) riducono al minimo l'insieme dei tipi di file (incluso eseguibile, oggetto condiviso).

Potrebbe anche essere possibile costruire file che possono essere validamente interpretati in più modi

È possibile, esiste un formato di file complicato: un pezzo di codice C che può essere interpretato come una descrizione dell'immagine. Inoltre ci sono diversi formati sempre più specifici: file di testo, file XML, un documento SOAP.


1
Man mano che i formati di file vanno, XPM non è così difficile. Considero "ingannevole" iniziare con qualcosa che sia sia un file JPEG valido sia un file ZIP valido.
Segna il
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.