Liste Füllen bzw. ASCII Umwandlung

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
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

Hallo zusammen,

ich versuche einen String aus Zahlen so zu teilen, dass ich sie wieder zurück zu dem jeweiligen ASCII Zeichen umwandeln kann.

Beispiel: 112101
-> dann splitte ich nach jedem 3. Zeichen: 112 101. Das funktioniert soweit.

Habe ich jedoch Zeichen, die unterschiedlich lang sind:
Beispiel: 97101
-> Wird es falsch gesplittet.

Meine Idee wäre, vor jede Zahl mit unterschiedlicher Länge eine 0 hinzuzufügen, damit alle dieselbe Länge haben.
Liste mit Zahlen; Input [99,100,101,1], Output: [099,100,101,001]

Oder hat jemand eine andere Idee, wie man aus einem langen String von Zahlen, automatisiert zu den dazugehörigen ASCII Werten umwandeln kann?:
Input: 1009799100
Output: dacd

Vielen Dank im Voraus
pychart
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@pychart: ich verstehe Deine Frage nicht ganz. Hast Du eine lange Reihe an Ziffern, die Du gerne irgendwie in Päckchen aufspalten möchtest? Das geht im allgemeinen nicht, weil es nicht eindeutig ist. Oder willst Du diese Zahlenreihe erst erzeugen? Dann stellt sich mir die Frage, warum?
BlackJack

@pychart: ”Output” müsste eher so aussehen: ``['099', '100', '101', '001']``, denn Zahlen haben ja keine führenden Nullen. Und das lässt sich mit den Format-Codes bei Zeichenkettenformatierung einfach hinbekommen.

Bleibt die Frage warum Du das machen willst, weil ``'dacd'`` ja doch deutlich kürzer ist als '100097099100'. Man könnte es auch hexadezimal mit zwei Zeichen pro Buchstaben darstellen '64616364', oder Base64 'ZGFjZA==', was allerdings nur bei etwas längeren Ausgangsdaten kürzer als hexadezimal ist. Vorteil bei den beiden letzteren Varianten ist zumindest das es dafür etwas in der Standardbibliothek gibt, und das Base64 eine Standardkodierung ist.
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

Zuerstmal vielen Dank für die Antworten.
Sirius3 hat geschrieben:@pychart: ich verstehe Deine Frage nicht ganz. Hast Du eine lange Reihe an Ziffern, die Du gerne irgendwie in Päckchen aufspalten möchtest? Das geht im allgemeinen nicht, weil es nicht eindeutig ist. Oder willst Du diese Zahlenreihe erst erzeugen? Dann stellt sich mir die Frage, warum?
Ich habe eine lange Reihe an Ziffern, die ich aufspalten möchte. Du hast recht, das geht tatsächlich nicht. Jedoch wurde ich aufmerksam, dass wenn ich ord(i) einfach bisschen zurückschiebe, ich dann zweistellige Integer bekomme -> ord(i)-23, jedoch funktioniert das bei chr(i)-23 nicht :(
BlackJack hat geschrieben:@pychart: ”Output” müsste eher so aussehen: ``['099', '100', '101', '001']``, denn Zahlen haben ja keine führenden Nullen. Und das lässt sich mit den Format-Codes bei Zeichenkettenformatierung einfach hinbekommen.

Bleibt die Frage warum Du das machen willst, weil ``'dacd'`` ja doch deutlich kürzer ist als '100097099100'. Man könnte es auch hexadezimal mit zwei Zeichen pro Buchstaben darstellen '64616364', oder Base64 'ZGFjZA==', was allerdings nur bei etwas längeren Ausgangsdaten kürzer als hexadezimal ist. Vorteil bei den beiden letzteren Varianten ist zumindest das es dafür etwas in der Standardbibliothek gibt, und das Base64 eine Standardkodierung ist.
dacd ist tatsächlich kürzer, jedoch laufen die Zahlen durch einen mathematischen Algorithmus, weshalb ich Buchstaben ersetzen muss. Hexadezimal war auch eine Idee, jedoch gibt es da auch Buchstaben, nicht?
Könntest du mir das mit Format-Codes näher erläutern, bitte?

Wie oben beschrieben, müsste ich entweder chr(i)-23 zum Laufen bringen oder deine Idee mit Format-Codes anschauen.

EDIT: chr(i+23) funktioniert, ich werde nun testen ob alles klappt und melde mich wieder. :D
EDIT2: Hat geklappt! Die ASCII Tabelle verschieben bis alle Ziffern zweistellig werden, dann parsen und splitten! :):

Code: Alles auswählen

ord(i)-23 & chr(i+23)
Kann geschlossen werden!

Lieben Gruß
BlackJack

@pychart: Das erklärt jetzt immer noch nicht was Du da eigentlich machst/machen willst. Es klingt sehr nach einer Lösung für ein ein Problem für das es sehr wahrscheinlich eine weniger schräge Lösung gibt.
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

Ich habe einen Algorithmus.
Ich gebe einen Text ein, wandle es in ASCII um, parse und habe nun eine große Zahl. Diese setze ich in den Algorithmus ein und bekomme eine andere Zahl raus.

Wenn ich von dieser neuen Zahl wieder zurück zu meinem Text kommen will, teile ich den langen Zahlenstring (hängt mit dem Alg. zusammen) -> rechne den Alg. zurück und bekomme nun die große Wurst wieder zurück. Dadurch, dass ich zweiziffern ASCIIs habe, teile ich die Wurst nach jeder 2. Zahl und wandle sie wieder zurück in den ursprünglichen Text. :D
Verständlich?
Bin mir ziemlich sicher, dass es elegantere Wege gibt, da ich aber kein Profi bin und alles funzt, reicht mir diese Variante!
BlackJack

@pychart: `int.from_bytes()` und `int.to_bytes()`. Man muss sich dazu die Länge merken, oder Nullbytes ausschliessen und eine zu grosse Länge angeben und dann gegebenenfalls Nullbytes entfernen. Dafür kann man so beliebige Bytes (ausser eventuell dem Nullbyte) und nicht nur ASCII-Buchstaben umwandeln.
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

BlackJack hat geschrieben:@pychart: `int.from_bytes()` und `int.to_bytes()`. Man muss sich dazu die Länge merken, oder Nullbytes ausschliessen und eine zu grosse Länge angeben und dann gegebenenfalls Nullbytes entfernen. Dafür kann man so beliebige Bytes (ausser eventuell dem Nullbyte) und nicht nur ASCII-Buchstaben umwandeln.
Bitte ein Beispiel, verstehe nicht was du meinst.
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@pychart: wenn es nur darum geht, einen beliebigen Text in eine große Zahl umzuwandeln, kann man auch »int.from_bytes« verwenden:

Code: Alles auswählen

>>> text = b"Hallo"
>>> int.from_bytes(text, "little")
478560411976
>>> (478560411976).to_bytes(5, "little")
b'Hallo'
Aber Vorsicht, falls der Text Null-Bytes enthält, denn führende Nullen gibt es bei Zahlen nicht.

Code: Alles auswählen

>>> text = b"Hallo\0"
>>> int.from_bytes(text, "little")
478560411976
BlackJack

Wobei mir gerade einfällt das man, zumindest wenn die Nullbytes kein Problem darstellen, sich die Länge nicht merken muss, sondern die Information mit `int.bit_length()` berechnen kann.
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

Sirius3 hat geschrieben:@pychart: wenn es nur darum geht, einen beliebigen Text in eine große Zahl umzuwandeln, kann man auch »int.from_bytes« verwenden:

Code: Alles auswählen

>>> text = b"Hallo"
>>> int.from_bytes(text, "little")
478560411976
>>> (478560411976).to_bytes(5, "little")
b'Hallo'
Aber Vorsicht, falls der Text Null-Bytes enthält, denn führende Nullen gibt es bei Zahlen nicht.

Code: Alles auswählen

>>> text = b"Hallo\0"
>>> int.from_bytes(text, "little")
478560411976
Gute Idee, jedoch kann ich sehr lange Zahlen wiederum nicht gebrauchen. Wenn ich sie aufspalten würde, ginge es: zB nach jeder 4. Zahl, jedoch muss dann die sehr lange Zahl gerade Stellen haben.
BlackJack

@pychart: Was um Himmels willen versuchst Du da zu machen? Wenn Du keine grosse Zahl haben willst dann nimm doch einfach den Codepoint für jedes Zeichen. Und dann wirklich als *Zahlen* und versuch nicht das dann irgendwie wieder als Zahldarstellung in eine Zeichenkette zu stecken die man an festen Grenzen aufteilen muss um an die einzelnen Zahlen zu kommen. Das klingt immer merkwürdiger. Beschreibe doch mal komplett das *eigentliche* Problem das gelöst werden soll, und nicht eine völlig verquere Lösung.
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

BlackJack hat geschrieben:@pychart: Was um Himmels willen versuchst Du da zu machen? Wenn Du keine grosse Zahl haben willst dann nimm doch einfach den Codepoint für jedes Zeichen. Und dann wirklich als *Zahlen* und versuch nicht das dann irgendwie wieder als Zahldarstellung in eine Zeichenkette zu stecken die man an festen Grenzen aufteilen muss um an die einzelnen Zahlen zu kommen. Das klingt immer merkwürdiger. Beschreibe doch mal komplett das *eigentliche* Problem das gelöst werden soll, und nicht eine völlig verquere Lösung.
'tschuldige, was ist ein Codepoint? Habe zwar gegooglet und Unicode etc. erhalten, jedoch kann ich mir immernoch nicht ganz vorstellen was du damit meinst.
BlackJack

@pychart: Das ist der Zahlenwert eines Unicode-Zeichens. Bei ASCII ist der gleich dem ASCII-Wert.
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

BlackJack hat geschrieben:@pychart: Das ist der Zahlenwert eines Unicode-Zeichens. Bei ASCII ist der gleich dem ASCII-Wert.
Gut zu wissen! :D
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

Hallo,
ich habe zum Spaß die Funktionen 'int.from/to_bytes' etc angeschaut, jedoch habe ich eine Frage:
Beispiel von Sirius3 [...]:
Sirius3 hat geschrieben:

Code: Alles auswählen

>>> text = b"Hallo"
>>> int.from_bytes(text, "little")
478560411976
>>> (478560411976).to_bytes(5, "little")
b'Hallo'
Wie kann ich 'int.to_bytes()' ohne der Länge des eigentlichen Textes verwenden? Hier 5, da 'hallo' 5 Zeichen enthält, nicht?

Lieben Gruß
BlackJack

@pychart: Wenn es keine (führenden) Nullbytes geben kann, kann man sich das aus der Bitlänge der Zahl ausrechnen, wie viele Bytes die Zahl braucht. Und die Bitlänge kann man wie schon gesagt mit der `bit_length()`-Methode ermitteln.
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

BlackJack hat geschrieben:@pychart: Wenn es keine (führenden) Nullbytes geben kann, kann man sich das aus der Bitlänge der Zahl ausrechnen, wie viele Bytes die Zahl braucht. Und die Bitlänge kann man wie schon gesagt mit der `bit_length()`-Methode ermitteln.
Wenn ich das am oben genannten Beispiel mache, kommt 39 raus, statt 5.

Code: Alles auswählen

(478560411976).bit_length()
 >>39
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@pychart: das ist der Unterschied zwischen Bits und Bytes: 8 Bit = 1 Byte, 39 Bit -> (39+7)//8 = 5 Bytes
pychart
User
Beiträge: 17
Registriert: Dienstag 27. Dezember 2016, 16:40

Sirius3 hat geschrieben:@pychart: das ist der Unterschied zwischen Bits und Bytes: 8 Bit = 1 Byte, 39 Bit -> (39+7)//8 = 5 Bytes
Gibt es hier keinen "Danke"-Button? :) Vielen Dank!
Antworten