Forum: PC-Programmierung Python konvertierung von int in ein einziges Byte, welches an String angehängt werden kann.


von Matthias (Gast)


Lesenswert?

Hallo zusammen,

ich versuche seit Stunden folgendes Python-Problem zu lösen.
Für ein serielles Protokoll soll eine Reihe an Bytes zusammengebaut 
werden.
Das Protokoll ist folgendermaßen definiert:
    #1. Byte = 0x55
    #2. Byte = ID
    #3. Byte = Len (data + 5Bytes)
    #4. Byte = Transmit-DATA
    #5. Byte = CRC16 (2Bytes)

Der zusammengesetzte Datensatz soll dann über sie serielle schnittstelle 
abheschickt werden.

Nun scheitere ich beim einsetzen von Len.

Mein bisheriger ansatz war:
transmit_data = "TEST"
tx_bytes = ""
tx_bytes = tx_bytes + bytes.fromhex('55').decode('utf-8')
print(tx_bytes) #Ausgabe : U -->Korrekt!
l = len(transmit_data)+5 # Ausgabe : 9 (int) -->Korrekt

#hier müsste ich nun irgendeine Möglichkeit finden die 9 (int) in ein 
einziges Byte b'\x09' umzuwandeln, welches dann an tx_bytes angehängt 
werden kann.
Jedoch sehe ich keine möglichkeit wie es gelingen kann, mit 
format(l,'x'), encode, hex....

Habe ich es vielfach mit verschiedenen Lösungsansätzen versucht, jedoch 
bekomme ich immer nur Fehlermeldungen dass eine der Konvertierungen 
nicht möglich ist.

Es wäre wirklich sehr, sehr schön wenn jemand eine Idee hätte wie die 
int 9 in ein einziges Byte b'\x09', tatsächlich dargestellt in nur einem 
einzigen Byte, nicht als String in Python umgewandelt und dem String 
angehängt werden kann.

Diese vermutlich eine Zeile hat mich nun schon ~3Stunden beschäftigt und 
ich bin bisher nur in Sackgassen geraten.

Schonmal vielen Dank für eure Vorschläge,
Matthias

von VN nn (Gast)


Lesenswert?


von Martin (Gast)


Lesenswert?

1
t = 9
2
b = str(t).encode()

von MaWin. (Gast)


Lesenswert?

Martin schrieb:
> str(t).encode()

Quark.
1
>>> b = bytes((9,))
2
>>> b
3
b'\t

von MaWin. (Gast)


Lesenswert?

MaWin. schrieb:
> b'\t

oh, da ist beim Kopieren das abschließende ' verlorengegangen. Aber ich 
denke es ist verständlich, was gemeint war.

von Bombadil (Gast)


Lesenswert?

Du kannst auch t.to_bytes(1,byteorder='big') benutzen. (Warum bei einem 
Byte die Byteorder angegeben werden muss kann man natürlich 
hinterfragen^^)

Wenn die Geschwindigkeit eine Rolle spielt, wäre ich bei VNnn: 
struct.pack("B", t)
Aber Laufzeit Geschichten sind ja eh erst mal eine andere Geschichte.

von Martin (Gast)


Lesenswert?

MaWin. schrieb:
> MaWin. schrieb:
>> b'\t
>
> oh, da ist beim Kopieren das abschließende ' verlorengegangen. Aber ich
> denke es ist verständlich, was gemeint war.

Brauchst Dich nicht zu rechtfertigen. Diese Art von Pfusch erwarte ich 
einfach von Dir.

von Rolf M. (rmagnus)


Lesenswert?

transmit_data = "TEST"
tx_bytes = bytearray()
tx_bytes.append(0x55)
…
tx_bytes += transmit_data.encode()

Matthias schrieb:
> l = len(transmit_data)+5 # Ausgabe : 9 (int) -->Korrekt

tx_bytes.append(l)

von MaWin. (Gast)


Lesenswert?

Martin schrieb:
> Diese Art von Pfusch erwarte ich einfach von Dir.

Hast du deine Medikamente wieder einmal nicht genommen?

von Matthias (Gast)


Lesenswert?

Vielen Dank für eure Antworten,
1
l = 5 + 4
2
print(l)
3
print(int.to_bytes(l,1,'big'))      --> b'\t'
4
tx_bytes.append(struct.pack("B",l)) --> b'\t'
5
print(l.to_bytes(1,'big'))          --> b'\t'
6
7
aber:
8
l = 5
9
print(l)
10
print(int.to_bytes(l,1,'big'))      --> b'\x05'
11
tx_bytes.append(struct.pack("B",l)) --> b'\x05'
12
print(l.to_bytes(1,'big'))          --> b'\x05'

ich kann das mit dem b'\t' nicht verstehen:
Dez: 116 / HEX : 74 / Bin : 01110100

Was soll dass mit 9 zu tun haben?

9 wäre für mich:
Dez: 9 / HEX : 9 / Bin : 00001001

Könnt ihr mir erklären wie man auf '\t' kommen kann?

-->Rolfs Ansatz probier ich gleoch aus...

von MaWin. (Gast)


Lesenswert?

Matthias schrieb:
> ich kann das mit dem b'\t' nicht verstehen:

man ascii
1
       Oct   Dec   Hex   Char                        Oct   Dec   Hex   Char
2
       ────────────────────────────────────────────────────────────────────────
3
       000   0     00    NUL '\0' (null character)   100   64    40    @
4
       001   1     01    SOH (start of heading)      101   65    41    A
5
       002   2     02    STX (start of text)         102   66    42    B
6
       003   3     03    ETX (end of text)           103   67    43    C
7
       004   4     04    EOT (end of transmission)   104   68    44    D
8
       005   5     05    ENQ (enquiry)               105   69    45    E
9
       006   6     06    ACK (acknowledge)           106   70    46    F
10
       007   7     07    BEL '\a' (bell)             107   71    47    G
11
       010   8     08    BS  '\b' (backspace)        110   72    48    H
12
       011   9     09    HT  '\t' (horizontal tab)   111   73    49    I

von Matthias (Gast)


Lesenswert?

MaWin. schrieb:
> 011   9     09    HT  '\t' (horizontal tab)

Oh mann, vielen Dank :-)
Wie kann man nur den tab mit dem t verwechseln :)

von Günter LenzDeine graphik sagt mit nichts, da ist n (Gast)


Lesenswert?

Die 255 in der Variable I speichern:
I = 255

Datentyp von I prüfen:
Type(I)

Also I ist eine Int-Variable.

Dann diese dreistellige Zahl 255 in ein Byte speichern,
255 ist ja die größte Zahl die in ein Byte reinpast:
By = chr(I)

Prüfen ob By wirklich nur ein einzelnes Byte ist:
len(By)

Ja, ist es, mit der int Zahl 255, oder hex Zahl FF.

von Matthias schrieb:
>Es wäre wirklich sehr, sehr schön wenn jemand eine Idee hätte wie die
>int 9 in ein einziges Byte

Lösung:
By = chr(9)

Das ganze wider rückgängig machen:
ord(By)

von Rolf M. (rmagnus)


Lesenswert?

Günter LenzDeine graphik sagt mit nichts, da ist n schrieb im Beitrag 
#6952755:
> Prüfen ob By wirklich nur ein einzelnes Byte ist:
> len(By)

Das bedeutet nicht, dass By genau ein Byte groß ist. Len gibt nicht die 
Größe eins Objekts in Bytes an, sondern die Anzahl an Elementen eines 
Containers. By ist ein String, und da steht ein Zeichen drin. Setz mal I 
auf 1000 und wiederhole das ganze.

: Bearbeitet durch User
von MaWin. (Gast)


Lesenswert?

Günter LenzDeine graphik sagt mit nichts, da ist n schrieb im Beitrag 
#6952755:
> Lösung:
> By = chr(9)

Die Lösung ist aber leider falsch, weil kein bytes rauskommt, sondern 
ein str.
1
>>> type(chr(9))
2
<class 'str'>

von Günter LenzDeine graphik sagt mit nichts, da ist n (Gast)


Lesenswert?

von Matthias schrieb:
>Es wäre wirklich sehr, sehr schön wenn jemand eine Idee hätte wie die
>int 9 in ein einziges Byte b'\x09', tatsächlich dargestellt in nur einem
>einzigen Byte, nicht als String in Python umgewandelt und dem String
>angehängt werden kann.

Welche Python Version benutzt du?
Python2.7 unterscheidet nicht zwischen Byte und String, da
ist alles das selbe. Da funktioniert es so wie ich es oben
schon beschrieben habe. Ich habe da mal etwas experimentiert.
Mit Python3 funktioniert es so nicht mehr. Da bin ich selber
auch noch am knobeln.

von Rolf M. schrieb:
>Setz mal I
>auf 1000 und wiederhole das ganze.

Bei Python2.7 kommt dann eine Fehlermeldung, da funktioniert
es nur bis 255.
Bei Python3 kommt keine Fehlermeldung,
ist aber als Datentyp Byte nicht zu gebrauchen, auch nicht
mit 255.

von MaWin. (Gast)


Lesenswert?

Günter LenzDeine graphik sagt mit nichts, da ist n schrieb im Beitrag 
#6954152:
> Python2.7 unterscheidet nicht zwischen Byte und String,

Python 2 ist seit über 2 Jahren End-of-Life.
Das nutzt hoffentlich niemand mehr freiwillig.

> Da bin ich selber auch noch am knobeln.

Mehrere Lösungen stehen hier im Thread.

von Rolf M. (rmagnus)


Lesenswert?

Günter LenzDeine graphik sagt mit nichts, da ist n schrieb im Beitrag 
#6954152:
> von Rolf M. schrieb:
>>Setz mal I
>>auf 1000 und wiederhole das ganze.
>
> Bei Python2.7 kommt dann eine Fehlermeldung, da funktioniert
> es nur bis 255.

Python 2 habe ich aus meinem Repertoire gestrichen.

> Bei Python3 kommt keine Fehlermeldung,
> ist aber als Datentyp Byte nicht zu gebrauchen, auch nicht
> mit 255.

Ich würde generell nicht auf die Idee kommen, Strings zum Speichern von 
Binärdaten zu missbrauchen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.