listy hex i int przekształacnie

0

Witam robię można powiedzieć sobie hex edytor plików binarnych i zatrzymałem się na chyba dość prostym zagadnieniu ale nie mogę go rozwiązać
Na załączonym obrazku jest ta sama lista to tylko przykład
Nie wiem jak z liczb wyrażonych w 8 bitach przechodzić na 16 i odwrotnie
Chodzi o listy , jak wyświetlać je w int i hex to wiem ale jak zamienić z 8 na 16 bitów to już nie
Za wszelka pomoc bardzo dziękuje

#lista liczb wyrażonych w 8 bitach
lista_int_8bit=[070,092,000,025,076,083,001,225]

#lista zamieniona na liczbę int ale 16 bitów
lista_int_16bit=[18012, 00025,  19527,  00025 ]

#ta sama lista ale wyrażona w hex 8 bitów
lista_hex_8bit=[0x46,0x5c,0x00,0x19,0x4c,0x47,0x00,0x19]

#ta sama liczba ale wyrażona w hex 16 bitów
lista_hex_16bit=[0x465c,0x0019,0x4c47,0x0019]
2

Nie wiem jak z liczb wyrażonych w 8 bitach przechodzić na 16 i odwrotnie

Co masz myśli przechodzić z 8 bitów na 16? Jak to przechodzić?

Chodzi o listy , jak wyświetlać je w int i hex to wiem ale jak zamienić z 8 na 16 bitów to już nie

Nie rozumiem. Masz na myśli reprezentację binarną(jak liczby są trzymane w pamięci komputera) czy formatowanie liczb do stringa w sposób czytelny dla człowieka?

ogrod123 napisał(a):

lista_int_8bit=[070,092,000,025,076,083,001,225]

Jesteś pewien, że to poprawny zapis?
Python (wersja 3.11.1) zwraca mi błąd:
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
Domyślam się, że miało być:

lista_int_8bit=[70,92,0,25,76,83,1,225]

?
(no chyba, że to jakiś zapis, którego moja wersja Pythona nie ogarnia).

#lista liczb wyrażonych w 8 bitach

BTW to, co sobie tam napiszesz, a jak to Python będzie trzymał pod spodem, to inna sprawa.

print(type(255))

wyświetla int (choć nie jestem pewien, w ilu bitach Python trzyma dane dla int)

0

Jak używasz np hexwin masz opcję wyświetlania komórek 8 bit lub 16 bit (jedna komórka 8 bit to jest 70 , druga komórka 8 bitowa to jest 92)
ale jak chcesz miedz dane w formie 16 bit to z tych dwóch robi się jedna [70,92]/8bit,8bit wychodzi [18012]16bit

0
ogrod123 napisał(a):

Jak używasz np hexwin masz opcję wyświetlania komórek 8 bit lub 16 bit (jedna komórka 8 bit to jest 70 , druga komórka 8 bitowa to jest 92)
ale jak chcesz miedz dane w formie 16 bit to z tych dwóch robi się jedna [70,92]/8bit,8bit wychodzi [18012]16bit

Możesz użyć przesunięcia bitowego, żeby przesunąć bity w lewo <<
https://realpython.com/python-bitwise-operators/#left-shift
potem to dodać do siebie albo użyć operatora | (bitowe OR)

0

Strasznie to rozpisałem w programie ale działa nie ma funkcji do tego zamieszczam kod

#lista liczb wyrażonych w 8 bitach
lista_int_8bit=[70,92,0,25,76,83,1,225]
#lista zamieniona na liczbę int ale 16 bitów
lista_int_16bit=[18012, 25,  19527,  25 ]
#ta sama lista ale wyrażona w hex 8 bitów
lista_hex_8bit=[0x46,0x5c,0x00,0x19,0x4c,0x47,0x00,0x19]
#ta sama liczba ale wyrażona w hex 16 bitów
lista_hex_16bit=[0x465c,0x0019,0x4c47,0x0019]

#print(lista_hex_16bit)
#print(lista_int_8bit[0:2])
#a_1_bin=bin(lista_int_8bit[0])
#a_2_bin=bin(lista_int_8bit[1])


a=format(lista_hex_8bit[0],'08b')
b=format(lista_hex_8bit[1],'08b')
print(a,b)

#printuje 01000110 (czyli 70)  01011100 (czyli 92)
c=a+b
print(c)
#printuje 0100011001011100

print(int(c,2))
# a tu printuje 18012  czyli łączy komurki
0

Czyli co, rozwiązałeś problem?

0

powiedzmy że tak . Ale jak by ktos miał fajny pomysł łączenia wartości w listach , lub znal gotowe funkcje to chętnie poczytam.
Ale muszę więcej poczytać o formatowaniu . Trochę dziwne to jest na przykład

zmienna=50     #daje nam int 255
zmienna_hex=hex(zmienna)     # daje nam co prawda wartośc 32 ale jako string 0x32
zmienna_bin=bin(zmienna)      # daje wynik 0b0110010  ale liczba binarna nie jest wyrażona w 8 bitach tylko 7 powinno być 0b00110010

dziwne rozwiązanie jest tego aspektu w python

1

Warto zainteresować się modułem struct. Przy pomocy funkcji pack i unpack możesz łatwo skonwertować inty, znaki, napisy na postać binarną i z powrotem. Poniżej prosty przykład jak listę intów 0..255 można zamienić na bufor bajtów, a potem go ponownie przekonwertować na tupla. Bufor ma ciekawą funkcje hex, która zamienia bajty na napis heksadecymalny z opcją wstawiana dowolnego znaku przestankowego między bajtami.

Taki bufor bajtów możesz możesz przekonwertować na różne typy, więcej znajdziesz w dokumentacji help(struc). W przykładzie jest sposób jak zinterpretować bajty jako liczby 16bitowe zarówno dla little i big endian:

#!/usr/bin/env python3

from struct import pack,unpack

lista_int_8bit=[70,92,0,25,76,83,1,225]
print(lista_int_8bit, len(lista_int_8bit))

pack_string = f"8B" # 8 unsigned chars
print(f"{pack_string=}")
bufor = pack(pack_string, *lista_int_8bit)

print(f"{bufor=}")
print(f"{bufor.hex(' ')=}")

print(f"{unpack(pack_string, bufor)=}")

unpack_string16_LE = f"<4H" # < little endian
unpack_string16_BE = f">4H" # > big endian
print(f"{unpack_string16_LE=}")
print(f"{unpack_string16_BE=}")

print(f"{unpack(unpack_string16_LE, bufor)=}")
print(f"{unpack(unpack_string16_BE, bufor)=}")

wynik działania

[70, 92, 0, 25, 76, 83, 1, 225] 8
pack_string='8B'
bufor=b'F\\\x00\x19LS\x01\xe1'
bufor.hex(' ')='46 5c 00 19 4c 53 01 e1'
unpack(pack_string, bufor)=(70, 92, 0, 25, 76, 83, 1, 225)
unpack_string16_LE='<4H'
unpack_string16_BE='>4H'
unpack(unpack_string16_LE, bufor)=(23622, 6400, 21324, 57601)
unpack(unpack_string16_BE, bufor)=(18012, 25, 19539, 481)

Zamiast funkcji hex lub bin do konwertowania lepiej nadaje się f-string, poniżej prosty przykład:

In [34]: lista_int_8bit=[70,92,0,25,76,83,1,225]

In [35]: '_'.join([f"{znak:02X}" for znak in lista_int_8bit])
Out[35]: '46_5C_00_19_4C_53_01_E1'

In [39]: ' '.join([f"{znak:08b}" for znak in lista_int_8bit])
Out[39]: '01000110 01011100 00000000 00011001 01001100 01010011 00000001 11100001'

1 użytkowników online, w tym zalogowanych: 0, gości: 1