iT邦幫忙

0

自己嘗試壓縮文檔,到底有多少效果?——(3.)創建字典壓縮文檔

  • 分享至 

  • xImage
  •  
import csv
with open('台灣郵遞區號.csv', newline='', encoding = "UTF-8", errors='ignore') as csvfile:
    lst = [i for i in csv.reader(csvfile)]

# 把list轉成string
string = ','.join(lst[0])

# 將字串編碼為位元組序列
en = string.encode('utf-8')
# 1byte 裡有256個編碼,完全沒有使用到的編碼, 共 170 個
not_use_bytes = [i for i in range(256) if i not in en]

# 最常出現的三種字串,先取代掉
en = en.replace(',=,=,=,=,'.encode('utf-8'), bytes([not_use_bytes[10]]))
en = en.replace(',=,=,=,'.encode('utf-8')  , bytes([not_use_bytes[11]]))
en = en.replace(',=,=,'.encode('utf-8')    , bytes([not_use_bytes[12]]))

# 找出 2717 個重複出現字,並按節省大小排序(下一章解釋)
lst = longestDupSubstring(en)

# 字典交換
for i in range(10*256+157):
    if i < 157: # 用 157 個 1byte 替換最常出現的重複字彙
        en = en.replace(lst[i], bytes([not_use_bytes[i+13]]))
    else: # 用 2560 個 2byte 替換其他字彙(b'\x00\x00' → b'\x09\xff'
'''
如果要替換的 bytes([(i-157) // 256, (i-157) % 256]) 已經出現在 en,就放棄替換
這一個小細節是我用2個多小時debug出來的慘痛經驗
最後找出原因,在使用 b'\x04\x00' 取代字串時,en裡已經出現 b'\x04\x00',所以未來解碼的時候就會出錯,把本來出現的 b'\x04\x00'也一併替換掉
我猜測可能是之前替換時 剛好替換的末尾是 \x04,而下一個的替換首字又是 \x00
不知道其他人有沒有除了放棄替換之外的其他方式呢?歡迎留言討論
'''
        if bytes([(i-157) // 256, (i-157) % 256]) in en:
            lst[i] = bytes([(i-157) // 256, (i-157) % 256])
        else:
            en = en.replace(lst[i], bytes([(i-157) // 256, (i-157) % 256]))

# 使用 .bin 儲存資料
with open('data.bin', 'wb') as file:
    file.write(en)

# lst 原本有 2717 項,再加上原始先取代的 3 項,共 2720 項
lst = b'\xff\xff'.join([',=,=,=,=,'.encode('utf-8'),',=,=,=,'.encode('utf-8'),',=,=,'.encode('utf-8')] + lst)
with open('dictionary.bin', 'wb') as file:
    file.write(lst)

# 儲存沒有使用到的編碼
with open("not_use_bytes.txt", "w", encoding = "UTF-8") as f:
    f.write(str(not_use_bytes)[1:-1])

data.bin (708,027 byte)
dictionary.bin (20,127 byte)

(708,027 byte + 20,127 byte)/2,915,093 byte = 25%
最終壓縮為原檔案 25% 大小

自己嘗試壓縮文檔,到底有多少效果?——(4.)題外話,如何快速搜尋相同字串


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言