繁体   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