python3,解析十六进制字节流为中文字符的方法

本文主要探讨了在使用pydicom库读取DICOM影像时遇到的tag乱码问题。作者在尝试dcmdump和gdcmdump工具时,发现tag值显示不正常。通过研究,了解到这涉及到Python2和Python3中处理字符串和字节的差异。解决方案是使用`encode('raw_unicode_escape').decode('GB18030')`方法将乱码转换为正确内容。示例代码展示了如何正确解析StudyDescription和BodyPartExamined的tag。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文由Markdown语法编辑器编辑完成。

1. 问题提出

近期在处理一家医院的DR影像时,发现用pydicom读取出来的相关tag(BodyPartExamined, SeriesDescription等)是乱码,而由于后续还需要基于这些tag的值进行判断。因此,当务之急就是需要把这些乱码的值,想办法解析为正确的内容。

通过本机的dcmdump或gdcmdump, 在显示本图的相关信息时,显示出来都不正常。或者是以省略号显示,或是以乱码显示。

在这里插入图片描述
从图中可以看到, 这个影像的SeriesDescription, 用dcmtk自带的命令行工具dcmdump来查看DICOM TAG的信息时, 显示出来的字段是乱码.
在这里插入图片描述
通过python的pydicom包, 读取出来的SeriesDescription和BodyPartExamined, 也都是乱码.

2. 问题调研与解决

这里其实涉及到了python2和python3, 在处理字符串和字节时的一些不同.
后来通过查询网络, 在https://cloud.tencent.com/developer/article/1564777 得到了启发.

在这里插入图片描述
备注,如果用unicode_escape, 仍然是乱码的话,可以替换成: raw_unicode_escape

import pydicom
ds = pydicom.read_file('path/to/dcm')
print(ds.StudyDescription)
# 'Êý×Ö»¯ÉãÓ°(DR)/Ë«ÊÖ+˫ϥ'
print(ds.StudyDescription.encode('raw_unicode_escape').decode('GB18030'))
# '数字化摄影(DR)/双手+双膝'

相关链接:

  1. 关于python3的编码:https://cloud.tencent.com/developer/article/1564777
### 字符集与十六进制字节码之间的换关系 字符集是指一组特定的字符集合及其编码方式,而十六进制字节码则是用来表示这些字符的一种数值形式。两者之间的换涉及字符编码的标准(如 ASCII、UTF-8 或 GBK)以及具体的实现逻辑。 --- #### 1. **字符集到十六进制字节序列的换** 字符集中的每一个字符都由其对应的编码值唯一标识。当我们将字符集换为十六进制字节序列时,实际上是将每个字符按照指定的编码规则映射为其二进制表示形式,再进一步将其以十六进制的形式展示出来。 ##### 示例:使用 UTF-8 编码 UTF-8 是一种常见的多字节编码方案,适用于大多数现代应用环境。下面展示了如何将字符串 `"你好"` 换为十六进制字节序列的过程: ```python def string_to_hex(input_string): """将输入字符串按 UTF-8 编码换为十六进制字节序列""" byte_sequence = input_string.encode('utf-8') # 将字符串编码为字节数组 hex_representation = byte_sequence.hex() # 将字节数组换为连续的十六进制字符串 return ' '.join([hex_representation[i:i+2] for i in range(0, len(hex_representation), 2)]) # 添加空格分隔每两个字符 # 测试用例 input_text = "你好" output_hex = string_to_hex(input_text) print(f"字符串 '{input_text}' 的十六进制字节序列为: {output_hex}") # 输出结果为 e4 bd a0 e5 a5 bd ``` 在这个过程中,`"你好"` 对应的 UTF-8 编码分别为 `e4 bd a0` 和 `e5 a5 bd`[^1]。 --- #### 2. **十六进制字节码到字符集的换** 反向操作是从十六进制字节码恢复原始字符集的内容。此过程依赖于已知的编码标准(例如 UTF-8)。具体做法是先将十六进制字符串解析为字节数组,随后依据目标编码对其进行解码。 ##### 示例:从十六进制还原至字符串 以下代码演示了如何将十六进制字节码 `'e4 bd a0 e5 a5 bd'` 还原为原始字符串 `"你好"`: ```python def hex_to_string(hex_input): """将十六进制字节序列按 UTF-8 解码为字符串""" bytes_object = bytes.fromhex(hex_input.replace(" ", "")) # 移除空格并将十六进制字符串换为字节数组 decoded_string = bytes_object.decode('utf-8') # 按照 UTF-8 编码解码 return decoded_string # 测试用例 input_hex = "e4 bd a0 e5 a5 bd" output_text = hex_to_string(input_hex) print(f"十六进制字节序列 '{input_hex}' 对应的字符串为: {output_text}") # 输出结果为 你好 ``` 在此处,`bytes.fromhex()` 函数负责将十六进制字符串化为字节数组,之后通过 `.decode('utf-8')` 完成最终的解码工作[^4]。 --- #### 3. **不同编码的影响** 值得注意的是,不同的字符编码会对换结果产生显著差异。例如,在 GBK 编码下,同样的中文字符可能会有不同的字节表达形式。因此,在实际应用中需明确使用的编码类型。 | 编码 | 输入 (`"你好"`) | 十六进制输出 | |-----------|-------------------------|-----------------------| | UTF-8 | `"你好"` | `e4 bd a0 e5 a5 bd` | | GBK | `"你好"` | `d6 d0 c8 fc` | 由此可见,即使是对同一个字符集进行处理,由于采用的不同编码机制,得到的具体字节流也可能完全不同[^1]。 --- #### 4. **总结** 无论是从字符集到十六进制字节序列还是反之,都需要清楚地知道当前正在使用的编码格式是什么样的。只有这样才能够保证整个换流程既高效又无误。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

inter_peng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值