固定长度数据字段和可变长度utf-8编码

时间:2012-12-20 16:35:58

标签: python encoding utf-8 character-encoding byte

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

我需要确保字符串适合固定的字节长度字段。由于utf-8是一个可变宽度编码,这使得使用强力来以固定的字节长度截断字符串,因为你可能会留下一部分多字节字符悬挂在最后。

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

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

这似乎已经破解了。如果它已经存在,我不想重新发明。

3 个答案:

答案 0 :(得分: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 具有靜電產生裝置之影

答案 1 :(得分:4)

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

因此,您可以毫无困难地构建自己的功能。只需确保您添加到字段中的最后一个字符的格式为0xxxxxx,或者格式为10xxxxxx,其中下一个字符(您未添加的字符)的格式不是10xxxxxx {1}}。即你确保你刚刚添加了一个单字节的UTF-8字符或多字节UTF-8字符的最后一个字节。然后,您只需添加0即可填写其余字段。

答案 2 :(得分: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中意外回答。我将算法更改为不太理想的算法,但更容易理解。