簡體   English   中英

將 Python 十六進制字符串解析為兩半

[英]Parsing Python hex string in half

我在通過以下請求拆分此十六進制字符串時遇到了麻煩。

#hex string byte layout Description
#0-799 Load data, 4 bytes each
#800-1599 Position data, 4 bytes each
#leading 0x has been removed

我正在嘗試使用 python len() 函數來查找總長度,將其除以一半,然后使用 [:middle value] 分割字符串的前半部分和 [middle value:] 的第二部分。 這是我的代碼。

#INSERT LIBRARIES
import matplotlib.pyplot as plt

#this hex string is from the sample given by theta

hex_string = '00706A450090574500F0484500C0394500802D45001027450050284500E0304500603E4500204D450010594500C05E4500505C4500F051450060414500C02D4500E01A4500C00C4500C0064500000B4500D019450060314500E04D4500006A450008804500A08545007884450030794500205F4500E03F4500D0214500F00A450080FF440070024500D0124500202E450060504500F0744500D08B4500009B4500A0A7450040B24500F8BB4500F0C54500D0D0450080DC450028E8450068F2450000FA450028FE4500D8FE4500F0FC4500B8F9450088F6450068F44500D8F34500C8F44500B8F6450028F94500A0FB4500F0FD45000C0046002401460058024600B803460038054600B8064600F4074600980846005C08460010074600B40446009001460050FC450040F6450048F2450068F1450020F4450040FA45006C01460044064600BC0A4600F80D4600280F4600CC0D4600B409460010034600C0F44500D0E04500F8CB4500C8B7450090A5450038964500308A45009881450060784500B072450010704500206E4500706A45000000005C8F0240D7A380408FC2CD409A9911413D0A3F4152B86E4152B89041F628AC41713DCA41A470EB413D0A08427B141C42CDCC314285EB4842C3F56042B81E79420A578842856B93423D8A9D4214AEA6420000AF42ECD1B6425C8FBE423D8AC6425C0FCF425238D8420000E2423333EC42E17AF64252380043ECD104439AD9084333330C43D7E30E43CD0C114348E11243299C1443146E1643D7631843146E1A43856B1C43A4301E43B89E1F43F6A82043B85E214329DC21431F45224385AB22430A1723435278234314AE23439A9923437B1423437B1422435C8F20437B941E4333331C438F821943CD8C16430A5713439AD90F433D0A0C4366E60743A4700343C375FD4214AEF34252B8E94252B8DF4271BDD542CDCCCB4285EBC1427B14B8428F42AE42A470A44200809A42CD4C9042F6A88542B81E75427B145E420AD74642F628304285EB1A4252B807429A99ED410000D0418FC2B5410AD79D410AD787413D0A6741713D4241A4702141EC5104413333D3400000A040CDCC5C4000000040295C4F3F0AD7A33D00000000'

#Signed Integer: A 16-bit signed integer ranging from -32,768 to +32,767
#Unsigned Integer: A 16-bit unsigned integer ranging from 0 to 65535. 
#signed 32 bit int range is -2147483648 to 2147483647
#unsigned 32 int range is 0 to 4294967295

#sampe hex string:#5C8F0240
#Converted 32 bit equivalent: 1552876096

#Card hex string byte layout Description

#0-799 Load data, 4 bytes each
#800-1599 Position data, 4 bytes each

#create a new function that scales the 32 bit unsigned integer position value into a float value. Assuming a stroke range of 0-168 inches and that the integer value is unsigned 32 bit
def u32int_pos_to_float(u32int_value):
    OldValue = u32int_value
    OldMin = 0
    OldMax = 4294967295
    NewMin = 0
    NewMax = 168
    NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
    return NewValue

#create a new function that scales the 32 bit unsigned integer load value into a float value. Assuming a load cell of 0-30000 lbs and that the integer value is unsigned 32 bit
def u32int_load_to_float(u32int_value):
    OldValue = u32int_value
    OldMin = 0
    OldMax = 4294967295
    NewMin = 0
    NewMax = 30000
    NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
    return NewValue

#Card hex string byte layout Description

#0-799 Load data, 4 bytes each
#800-1599 Position data, 4 bytes each

#A byte (or octet) is 8 bits so is always represented by 2 Hex characters in the range 00 to FF
#4 bytes = 32 bits

#Find the middle index of the hex_string and split the string into two halves

print(' ')
print('-----this is the start of the hex string conversion logic-----')
print(' ')
print('The hex string is: ' + hex_string)
print(' ')
print('hex string length: ' + str(len(hex_string)))
middle_of_String = int(len(hex_string)/2)
print('middle of string is:',middle_of_String,)
lastloadinstring = middle_of_String
startposinstring = middle_of_String

print('')
hex_load_string = hex_string[:lastloadinstring]
print(len(hex_load_string))
hex_pos_string = hex_string[startposinstring:]
print(len(hex_pos_string))

print(' ')
print('----Start of the hexadecial load and position lists from Hex String dividing in half----')
print(' ')
print('hex_load_string length:',len(hex_load_string))
print(hex_load_string)
print('hex_pos_string length:',len(hex_pos_string))
print(hex_pos_string)

#parse the hex strings into 4 byte chunks
hex_load_list = [hex_load_string[i:i+8] for i in range(0, len(hex_load_string), 8)]
hex_pos_list = [hex_pos_string[i:i+8] for i in range(0, len(hex_pos_string), 8)]

print(' ')
print('---start of the hexadecimal load and position 4 byte "chunks" list----')
print('----Note from developer: 0-799 Load data and 800-1599 Position data are 4 bytes each----')
print(' ')
print('hex_load_list length:',len(hex_load_list))
print(hex_load_list)
print('hex_pos_list length:',len(hex_pos_list))
print(hex_pos_list)

#convert each hex chunk to 32 bit unsigned integer
load_list_int = []
pos_list_int = []
for i in range(0, len(hex_load_list)):
    load_list_int.append(int(hex_load_list[i],16))
    pos_list_int.append(int(hex_pos_list[i],16))

print(' ')
print('----start of the load and position unsigned 32 bit integer list----')
print(' ')
print('load_list_int length:',len(load_list_int))
print(load_list_int)
print('pos_list_int length:',len(pos_list_int))
print(pos_list_int)

#using the new function, convert the 32 bit unsigned integers to a new list of floats

load_list_float = []
for i in range(0, len(load_list_int)):
    load_list_float.append(u32int_load_to_float(load_list_int[i]))

pos_list_float = []
for i in range(0, len(pos_list_int)):
    pos_list_float.append(u32int_pos_to_float(pos_list_int[i]))

print(' ')
print('----start of the load and position floating value lists----')
print('--these are scaled using the functions are the top of the code. All scaled as unsigned 32 bit integers---')
print('---engineering units for scaling in function comments-----')
print(' ')
print('load_list_float length:',len(load_list_float))
print(load_list_float)
print('pos_list_float length:',len(pos_list_float))
print(pos_list_float)

#create a scatter plot of the position and load data
plt.scatter(pos_list_float, load_list_float)
plt.xlabel('Position (inches)')
plt.ylabel('Load (lbs)')
plt.title('Position vs Load')
plt.show()

所以這就是我的困惑所在。規則說 #0-799 加載數據,每個 4 個字節和 #800-1599 位置數據,每個 4 個字節。 當我在“middle_of_string”上拆分字符串時,兩邊的數字都相等。 這是否意味着我要復制前半部分的最后一個值和后半部分的第一個值? 看起來 len() 函數計算元素而不是索引,因此不是從零開始的。 但是,規則顯然是基於 0 的。

我是 python 的新手,一直盯着這個太久了,所以任何幫助都將不勝感激。

當我在“middle_of_string”上拆分字符串時,兩邊的數字都相等。 這是否意味着我要復制前半部分的最后一個值和后半部分的第一個值?

不! 您正確地將字符串分成兩半。 假設s是一個 1600 個字符的字符串,那么:

s[:800]表示之前的所有元素,但不包括800。即元素 0 到 799(包括 0 到 799)。

s[800:]表示從 800 開始的所有元素,包括800。即從 800 到 1599 的元素。

這通常會讓初學者感到困惑,但您的代碼實際上是一個很好的例子,說明了為什么它是這樣定義的。 您可以在兩個表達式中使用相同的索引 800 來划分字符串,而不會遺漏或重復。

似乎 len() 函數計算元素而不是索引。

是的,如果你有一個 1600 個字符的字符串s那么最后一個字符是s[1599]len(s) == 1600

Python 文檔

內置函數 len() 返回序列的項目數。 當序列的長度為 n 時,索引集包含數字 0、1、…、n-1。 序列 a 的項目 i 由 a[i] 選擇。

序列也支持切片:a[i:j] 選擇索引為 k 的所有項目,使得 i <= k < j。 當用作表達式時,切片是相同類型的序列。 這意味着索引集被重新編號,使其從 0 開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM