2012-02-04 19 views
6

Ho diversi valori esadecimali che cerco di scrivere su un file. Sembra che Lua non lo supporti immediatamente, poiché sono tutti trattati come stringhe anziché come valori. Ho calcolato che avrei dovuto suddividere un valore esadecimale più lungo, ad esempio AABBCC in AA, BB, CC e utilizzare string.char() su tutti i loro valori decimali consecutivi per portare a termine il lavoro.Lua: scrittura di valori esadecimali come file binario

Esiste una funzione integrata che consente di scrivere direttamente tali valori senza prima convertirli? Ho usato caratteri di escape come "0xAA" e "\ xAA", ma quelli non funzionavano.

Modifica: Lasciatemi fare un esempio. Sto guardando un file di prova in un editor esadecimale:

00000000 00 00 00 00 00 00 ...... 

E voglio scrivere su di esso nel modo seguente con il "AABBCC" stringa:

00000000 AA BB CC 00 00 00 ...... 

quello che ottengo anche se con i caratteri di escape è:

00000000 41 41 42 42 43 43 AABBCC 

risposta

23

Io uso le seguenti funzioni per la conversione tra una stringa esadecimale e un "binario non elaborato":

function string.fromhex(str) 
    return (str:gsub('..', function (cc) 
     return string.char(tonumber(cc, 16)) 
    end)) 
end 

function string.tohex(str) 
    return (str:gsub('.', function (c) 
     return string.format('%02X', string.byte(c)) 
    end)) 
end 

Essi possono essere utilizzati come segue:

("Hello world!"):tohex()    --> 48656C6C6F20776F726C6421 
("48656C6C6F20776F726C6421"):fromhex() --> Hello world! 
+0

Perfetto! Proprio quello che stavo cercando. Molte grazie! – Zerobinary99

+0

Questa soluzione sembra aggiungere il valore esadecimale 0c0D (o 13) ad alcuni posti apparentemente casuali. Era così vicino a ciò di cui avevo bisogno. –

+1

Beh, stai scrivendo questo su Windows? Se sì, allora il problema è nelle [interruzioni di riga] (http://en.wikipedia.org/wiki/Line_break_ (calcolo)). Mentre su Unix/Linux/Mac OS X il newline è rappresentato da single '\ n' = 0x0A, su Windows quando si digita una nuova riga, incorpora due byte: 0x0D, 0x0A (13 10, CR + LF).Questo potrebbe essere il motivo per cui stai vedendo 0x0D in posti casuali. Prova a vedere se è vicino a 0x0A - se questo è il caso, usa gli strumenti di conversione per convertire in stile Unix (singolo '\ n'). –

2

In modo da avere una stringa come questa:

value = 'AABBCC' 

E vuoi stamparlo (o trasformarlo in una stringa) in questo modo?

'101010101011101111001100' 

Che ne dici di questo?

function hex2bin(str) 
    local map = { 
     ['0'] = '0000' 
     ['1'] = '0001' 
     ['2'] = '0010' 
     -- etc. up to 'F' 
    } 
    return str:gsub('[0-9A-F]', map) 
end 

Nota che lascia intatto qualsiasi carattere che non possa essere interpretato come esadecimale.

+0

No, io non voglio convertire i dati esadecimali, ma voglio scrivere una stringa esadecimale come valore esadecimale invece di una stringa. Permettetemi di migliorare la mia domanda di cui sopra. – Zerobinary99

2

Esiste una tale funzione perché è così facile scriverne una.

function writeHex(str,fh) 
    for byte in str:gmatch'%x%x' do 
     fh:write(string.char(tonumber(byte,16))) 
    end 
end 

Questo semplicemente scrive i valori nel file indicato dal filehandle fh.

+0

Non funziona per i valori esadecimali memorizzati come stringhe. Quale formato deve avere "str" ​​perché funzioni correttamente? – Zerobinary99

+0

Beh, sì, hai ragione, ho fatto un errore nel codice. Aggiustato. – jpjacobs

+0

Penso che tu intenda 'str: gmatch '% x% x'' poiché'% X' è la negazione di ciò che stai cercando. – greatwolf

Problemi correlati