3

我有一个 Python 项目,其中我在一个包含 utf-8 编码、NULL 填充、NULL 终止字符串的通信协议中 有一个固定字节长度的文本字段(NOT FIXED CHAR-LENGTH FIELD)。

我需要确保字符串适合固定的字节长度字段。由于 utf-8 是一种可变宽度编码,这使得使用蛮力以固定字节长度截断字符串是有风险的,因为您可能会在末尾留下部分多字节字符悬空。

是否有模块/方法/函数/等可以帮助我将 utf-8 可变宽度编码字符串截断为固定字节长度?

做空填充和终止的东西将是一个奖励。

这似乎是一个已经被破解的坚果。如果它已经存在,我不想重新发明它。

4

3 回答 3

5

让 Python 检测并消除任何部分或无效字符。

byte_str = uni_str.encode('utf-8')
byte_str = byte_str[:size].decode('utf-8', 'ignore').encode('utf-8')

这是因为 UTF-8 规范在字符的第一个字节中对后续字节数进行编码,因此可以轻松检测到丢失的字节。

编辑:这是此代码使用我从另一个问题中提取的随机东方字符串的结果。第一个数字是最大大小,第二个是 UTF-8 字符串中的实际字节数。

45 45 具有靜電產生裝置之影像輸入裝置
44 42 具有靜電產生裝置之影像輸入裝
43 42 具有靜電產生裝置之影像輸入裝
42 42 具有靜電產生裝置之影像輸入裝
41 39 具有靜電產生裝置之影像輸入
40 39 具有靜電產生裝置之影像輸入
39 39 具有靜電產生裝置之影像輸入
38 36 具有靜電產生裝置之影像輸
37 36 具有靜電產生裝置之影像輸
36 36 具有靜電產生裝置之影像輸
35 33 具有靜電產生裝置之影像
34 33 具有靜電產生裝置之影像
33 33 具有靜電產生裝置之影像
32 30 具有靜電產生裝置之影
31 30 具有靜電產生裝置之影
于 2012-12-20T17:23:09.243 回答
4

在 UTF-8 流中很容易看出给定字节是否位于给定字符字节流的开头(或不在)。如果字节是形式10xxxxxx那么它是字符的非初始字节,如果字节是形式0xxxxxx它是单字节字符,其他字节是多字节字符的初始字节。

因此,您可以轻松构建自己的功能。只需确保您添加到字段中的最后一个字符是 form 0xxxxxx,或者是10xxxxxx下一个字符(您没有添加)不是 form 的 form 10xxxxxx。即,确保您刚刚添加了一个单字节 UTF-8 字符或多字节 UTF-8 字符的最后一个字节。然后,您可以添加0s 来填写您的字段的其余部分。

于 2012-12-20T16:49:51.970 回答
0
def fit(s, l):
    u = s.decode("utf8")
    while True:
        if len(s) <= l:
            return s + "\0" * (l - len(s))
        u = u[:-1]
        s = u.encode("utf8")

应该是关于你需要的东西。也许你必须改进它;它未经测试。


我进行了编辑,因为我不小心用 C 语言回答了。我将算法更改为不是那么理想的算法,但更容易理解。

于 2012-12-20T16:55:47.820 回答