2012-02-04 23 views
6

Mam kilka wartości szesnastkowych, które próbuję zapisać do pliku. Wygląda na to, że Lua nie obsługuje tego po wyjęciu z pudełka, ponieważ wszystkie są traktowane jako łańcuchy zamiast wartości. Pomyślałem, że będę musiał podzielić dłuższą wartość szesnastkową, na przykład AABBCC na AA, BB, CC i użyć string.char() na wszystkich ich wartościach dziesiętnych kolejno, aby wykonać zadanie.Lua: zapisywanie wartości heksadecymalnych jako pliku binarnego

Czy jest wbudowana funkcja, która pozwala mi zapisywać takie wartości bezpośrednio, bez ich wcześniejszej konwersji? Użyłem znaków ucieczki, takich jak "0xAA" i "\ xAA", ale te nie wyszło.

Edytuj: Pozwól, że dam ci przykład. Patrzę na pliku testowego w edytorze hex:

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

I chcę napisać do niego w następujący sposób z ciągiem „AaBbCc”:

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

Co mogę chociaż z znaki ewakuacyjne jest:

00000000 41 41 42 42 43 43 AABBCC 

Odpowiedz

23

używam następujące funkcje do konwersji pomiędzy ciągiem szesnastkowym i „surowego binarny”:

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 

Mogą być używane w następujący sposób:

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

Idealnie! Właśnie tego szukałem. Wielkie dzięki! – Zerobinary99

+0

To rozwiązanie wydaje się dodawać wartość szesnastkową 0c0D (lub 13) do niektórych, pozornie przypadkowych miejsc. Było tak blisko tego, czego potrzebowałem. –

+1

Cóż, piszesz to w systemie Windows? Jeśli tak, to problem występuje w [line breaks] (http://en.wikipedia.org/wiki/Line_break_ (computing)). W systemie Unix/Linux/Mac OS X znak nowej linii jest reprezentowany przez pojedynczy '\ n' = 0x0A, w systemie Windows po wpisaniu nowej linii osadza dwa bajty - 0x0D, 0x0A (13 10, CR + LF).Być może dlatego widzisz 0x0D w przypadkowych miejscach. Spróbuj sprawdzić, czy jest blisko 0x0A - w takim przypadku użyj narzędzi do konwersji, aby przekonwertować na styl uniksowy (pojedynczy "\ n"). –

2

Więc masz ciąg tak:

value = 'AABBCC' 

A chcesz go wydrukować (lub przekształcić w ciąg) w ten sposób?

'101010101011101111001100' 

Co z tym?

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

Należy zauważyć, że pozostawia nietknięte znaki, które nie mogą być interpretowane jako szesnastkowy.

+0

Nie, ja nie chcę konwertuj dane szesnastkowe, ale chcę napisać ciąg szesnastkowy jako wartość szesnastkową zamiast ciągu. Pozwól, że poprawię moje powyższe pytanie. – Zerobinary99

2

Jest taka funkcja, ponieważ łatwo jest ją napisać.

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

To po prostu zapisuje wartości do pliku wskazywanego przez uchwyt pliku fh.

+0

Nie działa dla wartości szesnastkowych przechowywanych jako ciągi. Który z formatów musi być "str", aby działał poprawnie? – Zerobinary99

+0

Cóż, tak, masz rację, popełniłem błąd w kodzie. Naprawione. – jpjacobs

+0

Myślę, że masz na myśli 'str: gmatch '% x% x'', ponieważ'% X' jest zaprzeczeniem tego, czego szukasz. – greatwolf