Seite 1 von 2

merkwürdiger timestamp

Verfasst: Mittwoch 18. März 2009, 23:11
von #cousin#
Hi Zusammen,

ich bin aktuell etwas verzweifelt und hoffe hier Hilfe zu finden. Ich habe timestamps die folgendermaßen aussehen:

07D60A01080000 -> 10/1/2006 08:00:00 AM
07D60918080000 -> 9/24/2006 08:00:00 AM

Leider finde ich keinen Hinweis welcher Typ das ist und wie ich die HEX-Kette in ein bekanntes Zeitformat überführen kann.

Kann mir einer von euch da evtl. weiterhelfen?

Verfasst: Donnerstag 19. März 2009, 00:08
von lunar
Und wir sollen das jetzt erraten, mit noch weniger Informationen als du sie hattest? Du sagst ja noch nicht mal, welches Programm diese Ausgabe liefert und was das gezeigte Beispiel zu bedeuten hat ... ist "07D60A01080000 -> 10/1/2006 08:00:00 AM" nun eine Zeile der Daten, oder bedeutet das, dass die Zeile "07D60A01080000" zum Datum 2006-01-10T08:00 führt?

Verfasst: Donnerstag 19. März 2009, 07:28
von #cousin#
Hi,

tut mir leid für die wenigen Infos, leider habe ich selbst auch nicht sehr viel mehr.

Ich habe ein Speicherabbild eines Mobiltelefons. Dieses besteht zu 95% aus HEX-Werten ist aber kein Binary-file.

In dieser datei finden sich lange Zeilen die die angegebenen HEX-Werte enthalten:

07D60A01080000

die sich in folgendes Zeitformat überführen lassen:

10/1/2006 08:00:00 AM

Ich möchte nun mit einem Skript die ganzen HEX-Werte durchgehen und die "Zeitstempel" lesbar machen. Leider geht das nur, wenn ich weiss, wie ich diese Werte "umwandeln" kann.

Ich hoffe nun sind es mehr Infos und ihr könnt etwas damit anfangen.

Re: merkwürdiger timestamp

Verfasst: Donnerstag 19. März 2009, 07:30
von tordmor
#cousin# hat geschrieben:Hi Zusammen,

ich bin aktuell etwas verzweifelt und hoffe hier Hilfe zu finden. Ich habe timestamps die folgendermaßen aussehen:

07D60A01080000 -> 10/1/2006 08:00:00 AM
07D60918080000 -> 9/24/2006 08:00:00 AM

Leider finde ich keinen Hinweis welcher Typ das ist und wie ich die HEX-Kette in ein bekanntes Zeitformat überführen kann.

Kann mir einer von euch da evtl. weiterhelfen?
07D6 0A 01 08 00 00
2006 10 01 08 00 00

so richtig schwer ist das ja nicht.

Verfasst: Donnerstag 19. März 2009, 07:44
von #cousin#
ok, hab gerade auch herausgefunden, dass das einfach nur HEX -> DEZ ist, aber leider bekomm ich das in python nicht hin.

evtl. kann mir Jemand bei meinem Code helfen:

Code: Alles auswählen

fileList = open(path + "/" + "fileList", "r")
for file in fileList:
	file = file.split("\n")
	file = file[0]
	hex_fobj = open(cwd + "/" + file, "r")
	asciiFilename = file.split(".")
	asciiFilename = asciiFilename[0]
	for hex_line in hex_fobj:
        	asciiOutput = ""
        	for char in range(0, len(hex_line), 2):
                	if char < ( len(hex_line) - 2 ):
                        	hexString = hex_line[char] + hex_line[char + 1]
                               # non printable characters will be substituted with __
                        	if ( hexString > 0X20 and hexString < 0X7F):
                                	asciiString = chr(int(hexString, 16))
                                	asciiOutput = asciiOutput + asciiString
                        	else:
                                	asciiString = "__"
                                	asciiOutput = asciiOutput + asciiString
		# save ASCII files
		ascii_fobj = open(path + "/" + "cuttedPieces_ASCII" + "/" + asciiFilename + ".ascii", "a")
		ascii_fobj.write(asciiOutput)
		ascii_fobj.close()
	hex_fobj.close()
filelist.close()
dieser Code-Teil soll mir alle Dateien aus der "filelist" öffnen und die HEX-Werte darin in die dafür stehenden Zeichen umwandeln.

Also aus 1F soll S werden (zB)

Habe ich hier einen Denkfehler bzgl. der DEZ Werte, oder nen schwerwiegenden Programmierfehler?

Verfasst: Donnerstag 19. März 2009, 08:14
von BlackJack
@#cousin#: `file` ist der Name eines eingebauten Typen, den sollte man nicht an etwas anderes binden. Das sieht man hier am Syntaxhighlighting auch ganz gut. Ausserdem sind das in der Liste ja auch keine Dateien, sondern Datei*namen*.

Dann setzt man Dateipfade besser mit `os.path.join()` zusammen, statt Zeichenketten zu addieren.

Das Abschneiden des '\n' mittels `split()` ist etwas umständlich. Da würde ich entweder `rstrip()` verwenden, oder eine kleine Funktion schreiben, die testet, ob die Zeichenkette mit '\n' endet und dann gegebenenfalls die Zeichenkette davor mittels "slicing" zurück gibt.

Um die Endung eines Dateinamens zu ersetzen, würde ich `os.path.splitext()` verwenden. Die `split()`-Lösung funktioniert nicht richtig, wenn mehr als ein '.' in dem Namen vorkommt.

Für die Umwandlung der Hex-Zeile in eine Zeichenkette gibt's das `binascii`-Modul. `binascii.unhexlify()` wandelt alle korrekt Werte um, also mus man danach noch die nicht-druckbaren Zeichen durch etwas anderes ersetzen. Das ginge mit der `translate()`-Methode auf Zeichenketten. Zum Erstellen des Arguments für diese Methode könnte `string.printable` nützlich sein.

Ansonsten hättest Du auch mal verraten können, warum Du meinst, dass Deins nicht funktioniert. Gibt's eine Fehlermeldung? Wenn ja, welche? Oder gibt's ein unerwartetes Ergebnis? Wenn ja, welches? Bei welcher Eingabe?

Verfasst: Donnerstag 19. März 2009, 08:19
von tordmor
#cousin# hat geschrieben:

Code: Alles auswählen

if ( hexString > 0X20 and hexString < 0X7F):
string > int

sollte eigentlich einen Fehler geben, gibt aber bei mir immer True aus irgend einem Grund.

Verfasst: Donnerstag 19. März 2009, 08:24
von #cousin#
vielen Dank schonmal für eure Antworten, ich werde meinen code im Laufe des Tages mal dementsprechend abändern und euch heute Abend das Ergebnis berichten.

Mein bisheriger code gibt für dein Eingabe 07D60918080000 leider nur ____________ aus, d.h. er kann entweder nicht richtig umwandeln, oder die if-Bedingung verweist immer auf den else-Teil.

Verfasst: Donnerstag 19. März 2009, 09:50
von rayo
Hi

Vielleicht hilft dir das weiter:

Code: Alles auswählen

import struct
a = '07D60918080000'
b = a.decode('hex')
print struct.unpack('>H5B', b)
Du brauchst den Schritt "b = a.decode('hex')" ev. nicht, wenn deine Daten bereichts richtig Vorliegen (beim print gibt er dann '\x07\xD6....' aus)

Gruss

Verfasst: Donnerstag 19. März 2009, 13:13
von #cousin#
So, ich habe nun mal den Teil aus dem ganzen Skript herausgelöst um Fehler besser eingrenzen zu können.

Erkennt ihr einen Fehler, oder versteht Python die 07 D6 usw... nicht als HEX-Werte? Denn ich erhalte folgende Ausgabe:

Code: Alles auswählen

$ ./encode.py testfile.txt



----> opening file: testfile.txt

07D60918080000

07
output: 
D6
output: Ö
09
output: 	
18
output: 
08
output: 
00
output: 
00
output: 
Die Datei test.txt enthällt nur die angezeigte Zeile, sonst keinen Inhalt.


und hier der Programmcode:

Code: Alles auswählen

#!/usr/bin/python
#


# imports and initial values
import string
import sys
import os
import binascii
import struct


# open original file
filename = str(sys.argv[1])
fobj = open(filename, "r")
print "----> opening file: \033[0;31m" + filename + "\033[m"


# convert from HEX to ASCII
for line in fobj:
	print line
	output = ""
	for char in range(0, len(line), 2):
		if char < ( len(line) - 2 ):
			hexString = line[char] + line[char + 1]
			print hexString
			asciiString = binascii.unhexlify(hexString)
			print "output: " + asciiString
[/code]

Verfasst: Donnerstag 19. März 2009, 16:28
von BlackJack
@#cousin#: Hier fehlt bei Deiner Frage wieder der Teil mit der Beschreibung was Du erwartest. Das Programm sieht so nämlich okay aus, und das ist auch genau die Ausgabe, die ich von dem Programm erwarten würde. Warum denkst Du die Hex-Werte würden nicht richtig erkannt? Das werden sie nämlich.

`unhexflify()` kann übrigens mehr als ein Byte dekodieren, dass heisst Deine Schleife ist viel zu kompliziert. Ungetestet:

Code: Alles auswählen

    for byte in binascii.unhexlify(line):
        print 'output:', byte

Verfasst: Donnerstag 19. März 2009, 17:35
von #cousin#
wie ich im ersten Post schon beschrieben habe, sollte der String

07D60918080000

zu

9 24 2006 08 00 00

umgewandelt werden. Leider gibt mein Skript aber keine druckbaren Zeichen aus. Also gehe ich davon aus, dass hier ein Fehler in meinem Skript ist.

Verfasst: Donnerstag 19. März 2009, 17:43
von BlackJack
Naja Du musst die Bytewerte der Zeichen in Zahlen umwandeln. Das geht in diesem Fall dann am einfachsten mit dem `struct`-Modul. Siehe rayo's Beitrag.

Verfasst: Freitag 20. März 2009, 01:32
von #cousin#
super, vielen Dank für die Hinweise, nun geht es in Einzelteilen, muss nun nur noch einen Weg finden wie ich es sinnvoll zusammenführe.

Dieser Teil wandelt das Datum um:

Code: Alles auswählen

decString = line.decode('hex')
decString = struct.unpack_from('>H5B', decString)
year = str(decString[0])
month = str(decString[1])
day = str(decString[2])
hour = str(decString[3])
if len(hour) == 1:
	hour = "0" + hour
minute = str(decString[4])
if len(minute) == 1:
	minute = "0" + minute
print "---> DEC date and time: \033[0;32m" + year + "-" + month + "-" + day + "  " + hour + ":" + minute + "\033[m"

der Teil wandelt den HEX-Stream in einen ASCII-Stream ohne Stuerzeichen um:

Code: Alles auswählen

for dataFile in fileList:
	dataFile = dataFile.split("\n")
	dataFile = dataFile[0]
	hex_fobj = open(cwd + "/" + dataFile, "r")
	asciiFilename = dataFile.split(".")
	asciiFilename = asciiFilename[0]
	for hex_line in hex_fobj:
        	asciiOutput = ""
               	for char in range(0, len(hex_line), 2):
                	if char < ( len(hex_line) - 2 ):
                                hexString = hex_line[char] + hex_line[char + 1]
                                asciiString = binascii.unhexlify(hexString)
                                asciiString = filter(lambda x: x in string.printable, asciiString)
                                asciiOutput = asciiOutput + asciiString
                asciiOutput = asciiOutput + "\n"
		# save ASCII files
		ascii_fobj = open(path + "/" + "cuttedPieces_ASCII" + "/" + asciiFilename + ".ascii", "a")
		ascii_fobj.write(asciiOutput)
		ascii_fobj.close()
	hex_fobj.close()

Verfasst: Freitag 20. März 2009, 06:56
von Zap
Mach dir das Leben leichter und benutzer mindestens das time oder besser noch das datetime modul. Damit kannst du dir eine menge Code ersparen.

Verfasst: Freitag 20. März 2009, 08:36
von BlackJack
@#cousin#: Vielleicht solltest Du Dich mal mit Funktionen auseinandersetzen, um die Teillösungen sauber zu trennen und wiederverwendbar zu machen.

Und für Zeiten und Datumsangaben gibt es zum einen das `datetime`-Modul und zum anderen hätte man auch Deine manuelle Methode mit Zeichenkettenformatierung über den ``%``-Operator auf Zeichenketten wesentlich kompakter hinbekommen. Ungetestet:

Code: Alles auswählen

year, month, day, hour, minute = struct.unpack('>H4B', line.decode('hex'))
print 'Date and time: %d-%02d-%02d  %02d:%02d' % (year, month, day, hour, minute)

Verfasst: Sonntag 29. März 2009, 13:44
von #cousin#
Hi Zusammen,

die Hinweise zu dem date-time-modul habe ich nun ebenfalls einfließen lassen, vielen Dank für den Hinweis.

Aber ich habe gerade bemerkt, dass ich ein anderes Problem habe. Die Funktion:

Code: Alles auswählen

asciiString = filter(lambda x: x in string.printable, asciiString)
filtert mir zwar alle Werte raus, die Steuerzeichen enthalten, aber leider auch Umlaute und ß.

Wie kann ich die filterfunktion dazu bringen, dass er mir diese Zeichen nicht filtert?

Verfasst: Sonntag 29. März 2009, 14:05
von BlackJack
@#cousin#: Falls die Daten in einer 1-Byte-pro-Buchstabe-Kodierung vorliegen, einfach `string.printable` plus die zusätzlichen Bytewerte für die Zeichen für den Test verwenden!?

Dann solltest Du aber den Namen `asciiString` ändern, denn ASCII enthält keine Umlaute.

Verfasst: Sonntag 29. März 2009, 16:07
von #cousin#
ok, danke, habs nun so gemacht:

Code: Alles auswählen

asciiString = filter(lambda x: x in string.printable or x == "\xdf" or x == "\xfc" or x == "\xf6" or x == "\xe4" or x == "\xdc" or x == "\xd6" or x == "\xc4", asciiString)
kann ich das mit nem Array, oder mit ner Liste irgendwie verkürzen?

Verfasst: Sonntag 29. März 2009, 17:15
von HWK
Statt

Code: Alles auswählen

x == 'a' or x == 'b' or x == 'c'
lieber

Code: Alles auswählen

x in 'abc'
MfG
HWK