Python 3 int -> bytearray

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44

Hi zusammen,

um eine Hash funktion zu testen brauche ich ein 16x16 Byte großes (Byte)Array gefüllt mit fortlaufenden werten.
D.h. an Stelle 1 befindet sich ein bytearray mit: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
An Stelle 2 befindet sich ein bytearray mit: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
An Stelle 10000 befindet sich ein bytearray mit: 00 00 00 00 00 00 00 00 00 00 00 00 00 27 10
Und an Stelle 39274091 efindet sich ein bytearray mit: 00 00 00 00 00 00 00 00 00 00 00 02 57 46 6B

usw.

Nun wollte ich einfach einen Zähler in einer Schleife hochlaufen lassen und das "Ergebnis" in ein bytearray wandeln welches dann der Liste hinzugefügt wird.
Nur wie mache ich das unter Pythen 3 ? Und zwar so das ich die einzelnen Stellen des Arrays auch noch gezielt ansprechen kann - Also ähnlich einer ArrayList unter Java ...
Scheinbar behandelt bytearray das Ganze als "char" anstatt "byte" type.
BlackJack

@may24x: Ich denke Du siehst Probleme wo keine sind.

Code: Alles auswählen

In [1]: a = bytearray('abc')

In [2]: a
Out[2]: bytearray(b'abc')

In [3]: a[0]
Out[3]: 97

In [4]: a[1]
Out[4]: 98
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44

Äh, ich brauche aber keine Strings. Sondern ein Integer soll hochgezählt werden. Von 0 bis 2^16. Dieser Integer soll als Bytearray gespeichert werden sodaß ich auf jede Zelle zugreifen kann.
BlackJack

@may24x: Okay vielleicht war das erstellen etwas irreführend:

Code: Alles auswählen

In [8]: a = bytearray([0, 1, 2, 3])

In [9]: a
Out[9]: bytearray(b'\x00\x01\x02\x03')
Ansonsten bleibt's beim ersten Beispiel. Bytearrays leisten das was Du haben willst.
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44


Code: Alles auswählen

a = 1234567890
bt = bytearray()
bt = a
print(bt[0]) 
TypeError: 'int' object is not subscriptable
BlackJack

@may24x: Ähm, das ist ja irgendwie klar wenn Du ein `int` an den Namen `bt` bindest, dass man da keinen Indexzugriff machen kann. Das hat ja überhaupt nichts damit zu tun wie `bytearray`\s funktionieren. Wenn Du hier etwas anderes erwartet hast, dann hast Du zuweisungen an Namen in Python generell nicht verstanden. Wenn man einen Wert an einen Namen bindet, dann wird genau das getan: der Wert wird an den Namen gebunden. Ob der Name vorher schon mal an einen anderen Wert gebunden war oder gar welchen Typ dieser Wert hatte ist völlig egal.

Wenn Du eine Zahl auf mehrere Bytewerte aufteilen willst, dann wirst Du schon Code schreiben müssen, der das tut. Und nicht hoffen dass das auf magische Weise passiert.
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44

Es gibt also keine "Möglichkeit" für eine solche Typenwandlung ? Was ich versuche ist ja eine (sehr) große Integer Zahl in ein Byte Array zu "übersetzen"
BlackJack

@may24x: Natürlich gibt es eine Möglichkeit. Du musst das nur programmieren.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ab Python 3 ist es sogar nicht mal so schwer, da Zahlen vom Typ `int` eine praktische `.to_bytes()`-Methode erhalten haben.

So erstellt man z.B. ein 5-stelliges Big-Endian Bytearray für die Zahl 10000:

Code: Alles auswählen

>>> x = 10000
>>> result = bytearray(x.to_bytes(5, 'big'))
>>> result
bytearray(b"\x00\x00\x00\'\x10")
Da im Eingangspost die hexadezimale Schreibweise gewählt wurde, hier nochmal zum Vergleich:

Code: Alles auswählen

>>> hex(result[-1])
'0x10'
>>> hex(result[-2])
'0x27'
Gemäß der Anforderung (so wie ich sie verstanden habe) würde man jetzt also alle Zahlen von 0 bis 2^16 durchlaufen und nach dem gezeigten Vorgehen deren "Bytearray-Versionen" in einer Liste speichern, wobei für die Größe eben nicht 5, sondern die gewünschte Größe (16*16?) angegeben werden müsste.

Selbstredend kann man die explizite Erzeugung des Bytearrays auch weglassen und einfach mit dem Ergebnis der Integer-Methode arbeiten, falls das ausreicht.
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44

Ich versuche gerade mein Bytearray in ein Anderes zu integrieren:

Code: Alles auswählen

ary=bytearray()

for t in range (0,(2**128)):
         ar=bytearray(t.to_bytes(16,'big')
         ary.append(ar)

Aber ich bekomme:
ary.append(ar) Syntax Erro: invalid syntax
... aber was soll da flasch sein ?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nichts. Bei Syntax-Fehlern muss man etwas genauer hinschauen, denn die angezeigte Stelle ist die, an der der Parser aussteigt. Mindestens die Zeile davor sollte man sich anschauen .. so auch in diesem Fall ;)
BlackJack

@may24x: Semantisch ist das trotzdem falsch weil `bytearray`\s grundsätzlich eindimensional sind und dementsprechend `append()` nur einen einzelnen Bytewert als Argument nimmt. Du könntest `extend()` verwenden, aber das ändert nichts daran, dass es ein eindimensionales Array bleibt.

Und dann solltest Du vielleicht mal über den Speicherverbrauch nachdenken. Rechne den mal aus. Das sprengt jeden Adressraum und selbst die NSA dürfte nicht so viel Massenspeicher haben um dieses Array zu speichern.

Edit: Mal vom Speicherverbrauch abgesehen: Wenn jeder Schleifendurchlauf nur eine Picosekunde dauert, würde das Programm trotztdem 10.783.128 Trillionen Jahre laufen.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

may24x hat geschrieben:um eine Hash funktion zu testen brauche ich ein 16x16 Byte großes (Byte)Array gefüllt mit fortlaufenden werten.
Was willst du eigentlich damit genau testen können? Nur zur Info: Tests decken üblicherweise *nicht* jede erdenkliche Eingabe ab. Es werden ein paar übliche Sachen und vielleicht noch Randfälle getestet und das war's. Das gibt zwar theoretisch keine hundertprozentige Sicherheit über das korrekte Funktionieren der getesteten Funktion (oder etwas ähnlichem), aber da man halt aufgrund der zur Verfügung stehenden Ressourcen meistens nicht beliebig viel testen kann, muss man dementsprechend einen annehmbaren Kompromiss finden, indem man die Testfälle sinnvoll reduziert.
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44

Ich versuche eine Einweg Hash Funktion zu basteln. Der "Fingerprint" ist 16 Bytes lang. Also ist die Menge aller möglichen Kombinationen 16x16
Die will/wolte ich in einer (quasi) ArrayList speichern um zu sehen wann und wieviele Kollisionen auftauchen.

Hm, na ja vielleicht sollte man erst mit 8 Bytes anfangen :mrgreen:

Die Hashfunktion soll - im Gegensatz von SHA oder MD5 - Datentreduktion liefern. D.h. Von den 16 Bytes Ausgangs Zahlen bleiben danach noch 8 Byte übrig.
Das ist ein "Verlust" von 50%. Somit ist es unmöglich auf die Originalzahlen zu kommen - auch wenn man die Hashfunktion kennt.

Das "Problem" sind Kollisionen. D.h. Nach der Hashfunktion können mehrere (Original) Byteketten das selbe Ergebnis liefern.
Das Script sollte mir nun zeigen welche Kombinationen welche Kollisionen liefern und wieoft ...
BlackJack

@may24x: Die Beschreibung ist total wirr. Was ist bitte der „Fingerprint”? Die Menge welcher Kombinationen ist 16×16? Mit 16 Bytes gibt es nicht 256 sondern 2^128 Kombinationen. Die alle aufzuzählen dauert zu lange als das ein Rechner das könnte. Und die kann man auch nicht speichern selbst wenn man sie in absehbarer Zeit aufzählen könnte. Und warum willst Du die überhaupt speichern?

Auch bei 8 Bytes würde es immer noch sehr lange dauern die Kombinationen aufzuzählen. Gehen wir wieder von einer Picosekunde pro Schleifendurchlauf auf, so dauert es immer noch 7 Monate. Die dabei anfallenden cirka 147 Exabytes kann die NSA vielleicht speichern, aber Du sicherlich nicht, und schon gar nicht der Hauptspeicher des Rechners.

Das was Du vorhast ist „brute force” einfach nicht möglich. Wenn Du die Verteilung wissen willst, musst Du das entweder mathematisch berechnen oder abschätzen, oder einfach auf die Funktion vertrauen.
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44

@BlackJack: UM so besser denn darum geht's "eigentlich". Das Ganze soll nicht (in absehbarer Zeit) zurückrechenbar sein.

Aber mal zurück zum eigentlichen Thema. Wieso kommt die Fehlermeldung ?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

may24x hat geschrieben:@BlackJack: UM so besser denn darum geht's "eigentlich". Das Ganze soll nicht (in absehbarer Zeit) zurückrechenbar sein.
Über die Qualität deines Ansatzes wurde doch gar keine Aussage getroffen. Nur weil es so viele Kombinationsmöglichkeiten gibt, heißt dies nicht, dass diese auch alle realisiert werden. Das wäre nur bei perfektem Hashing der Fall. Da aber keiner deinen Algorithmus kennt, kann dein Ansatz natürlich beliebig schlecht sein. Unter Umständen lassen sich also sogar Kollisionen konstruktiv erzeugen.
may24x hat geschrieben:Aber mal zurück zum eigentlichen Thema. Wieso kommt die Fehlermeldung ?
Hat cofi dir schon gesagt.
Das Leben ist wie ein Tennisball.
may24x
User
Beiträge: 48
Registriert: Montag 2. September 2013, 06:44

may24x hat geschrieben:Aber mal zurück zum eigentlichen Thema. Wieso kommt die Fehlermeldung ?
Hat cofi dir schon gesagt.
ooops, hab ich überlesen. OK, ist gefixed :wink:
BlackJack

@may24x: Ich versteh's nicht: Du willst etwas Programmieren bei dem Du von Anfang an weist, dass es in einem `MemoryError` endet bevor auch nur irgend etwas sinnvolles gemacht wurde? Du erzeugst einfach nur sinnfreie Daten bis der Speicher voll ist? *Das* kann man auch einfacher haben. ;-)
Antworten