2012-12-20 115 views
3

我有一個Python項目中,我在COMM協議具有固定字節長度文本字段(不固定CHAR-LENGTH FIELD)包含UTF- 8編碼,NULL填充,NULL結束字符串。固定長度的數據字段和可變長度UTF-8編碼

我需要確保一個字符串適合固定的字節長度字段。由於utf-8是一種可變寬度編碼,因此可以使用蠻力以固定字節長度截斷字符串,因爲您可能會在最後留下多字節字符的一部分。

是否有一個模塊/方法/函數/等,可以幫助我截斷utf-8可變寬度編碼的字符串到一個固定的字節長度?

無填充和終止的東西將是一種獎勵。

這似乎是一個已經被破解的螺母。如果它已經存在,我不想重塑它。

回答

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 具有靜電產生裝置之影 
+0

謝謝。這看起來像一個非常簡潔的解決方案。 –

4

在UTF-8流中很容易看出給定字節是否在給定字符的字節流的開始(或不在)。如果字節的格式爲10xxxxxx,那麼它是一個字符的非起始字節,如果該字節的形式爲0xxxxxx它是單字節字符,而其他字節是多字節字符的起始字節。

因此,你可以建立自己的功能沒有太多的困難。只要確保您添加到字段的最後一個字符的形式爲0xxxxxx,或者形式爲10xxxxxx,那麼下一個字符(不添加的字符)的格式不是10xxxxxx。即你確定你剛剛添加了一個字節的UTF-8字符或多字節UTF-8字符的最後一個字節。然後,您可以只添加0 s來填寫您的字段的其餘部分。

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中回答我改變算法,以一個不是最理想的,但更容易理解。

+0

爲什麼您將一個C/C++答案留給Python問題? –

+0

我用Python標記了這篇文章,但沒有在文章中提到它。我可以在我的帖子中更清楚。固定。 –

+0

WHOOPS!抱歉。我可能認爲...沒關係。我會改變它:-) – glglgl