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

3
我有一个Python项目,其中我有一个固定的字节长度文本字段(不是固定的字符长度字段),该字段包含一个utf-8编码、NULL填充、NULL终止的字符串。
我需要确保字符串适合固定的字节长度字段。由于utf-8是一种可变宽度编码,因此使用暴力方法在固定的字节长度处截断字符串可能会导致多字节字符的一部分悬空在末尾,这使得情况变得复杂。
是否有模块/方法/函数等可以帮助我将utf-8可变宽度编码字符串截断为固定的字节长度?能够执行null填充和终止的操作会更好。
这似乎是已经被解决的难题。如果已经存在某些方法,我就不想重新发明轮子了。
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 具有靜電產生裝置之影

谢谢。这看起来是一个非常简洁的解决方案。 - Dave L.

4
在UTF-8流中,很容易看出给定字节是否在给定字符的字节流的开头(或不是)。如果该字节为10xxxxxx形式,则它是一个多字节字符的非初始字节;如果该字节为0xxxxxx形式,则它是一个单字节字符;其他字节则是多字节字符的初始字节。
因此,您可以轻松构建自己的函数。只需确保您添加到字段的最后一个字符是以0xxxxxx形式结束的,或者是以10xxxxxx形式结束且下一个字符(您未添加)不是以10xxxxxx形式结束的。也就是说,确保您刚刚添加了一个一字节的UTF-8字符或多字节UTF-8字符的最后一个字节。然后,您只需添加0以填充您的字段的其余部分即可。

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语言回答了。我将算法更改为一个不太优化的算法,但更容易理解。


你为什么在一个Python问题中留下了一个C/C++的答案? - Mark Ransom
我在这篇帖子中打了Python的标签,但没有在帖子中提到它。我本可以在帖子中更清楚地表达。已修复。 - Dave L.
啊哦!抱歉。我可能想太多了...算了,我会改正它 :-) - glglgl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接