照片與語音不是文字——認識二進位檔與雜湊驗證
安全保存水井三寶影像、長者口述錄音及設備原始檔,並確認備份前後一個位元組都沒有改變。
完成本篇後,你能分辨文字與二進位資料,使用
rb、wb、xb 讀寫位元組,以分塊方式處理大型媒體檔,使用Base64進行文字化傳輸,並用SHA-256驗證檔案完整性。一、為什麼照片不能用UTF-8讀?
文字檔需要編碼把位元組解讀成字元;JPEG、PNG、MP3、WAV等檔案則有自己的二進位格式。若以 encoding="utf-8" 開啟照片,Python會嘗試把影像位元組解碼為文字,通常產生 UnicodeDecodeError。
| 資料 | Python型別 | 常用模式 |
|---|---|---|
| 逐字稿、CSV、JSON | str | r、w,指定編碼 |
| 照片、錄音、PDF、韌體 | bytes | rb、wb,不指定編碼 |
二、認識bytes
text = "水井三寶"
data = text.encode("utf-8")
print(type(text), len(text))
print(type(data), len(data))
print(data)
print(data.decode("utf-8"))bytes 是0到255整數組成的不可變序列。文字可經編碼變成位元組,但照片位元組本身不應任意 decode() 成文字。
三、讀取二進位檔的前幾個位元組
from pathlib import Path
def read_header(path, size=16):
path = Path(path)
with path.open("rb") as file:
return file.read(size)
# 實際使用時換成資料副本
# header = read_header("照片/水井三寶.jpg")
# print(header)
# print(header.hex())許多檔案格式有特徵位元組,但只檢查檔頭不能證明整份檔案安全或內容正確。副檔名與檔頭都只能作為初步判斷。
四、建立教學用二進位檔
from pathlib import Path
path = Path("教學資料.bin")
sample = bytes([0, 1, 2, 127, 128, 254, 255])
with path.open("xb") as file:
file.write(sample)
with path.open("rb") as file:
restored = file.read()
print(restored)
print(list(restored))xb 表示排他建立二進位檔;目標已存在時會拒絕覆蓋,適合保護重要資料。
五、分塊讀取大型照片或錄音
使用 read() 一次讀完整段錄音可能占用大量記憶體。分塊處理能固定每次使用量。
from pathlib import Path
def count_bytes(path, chunk_size=64 * 1024):
total = 0
with Path(path).open("rb") as file:
while chunk := file.read(chunk_size):
total += len(chunk)
return total
print(count_bytes("教學資料.bin"))六、安全複製:目標存在就停止
from pathlib import Path
def copy_binary(source, target, chunk_size=1024 * 1024):
source = Path(source)
target = Path(target)
if not source.is_file():
raise FileNotFoundError(f"來源不存在:{source}")
target.parent.mkdir(parents=True, exist_ok=True)
with source.open("rb") as input_file:
with target.open("xb") as output_file:
while chunk := input_file.read(chunk_size):
output_file.write(chunk)
return target
# copy_binary("原始媒體/訪談.wav", "備份/訪談.wav")七、用SHA-256建立檔案指紋
import hashlib
from pathlib import Path
def sha256_file(path, chunk_size=1024 * 1024):
digest = hashlib.sha256()
with Path(path).open("rb") as file:
while chunk := file.read(chunk_size):
digest.update(chunk)
return digest.hexdigest()
print(sha256_file("教學資料.bin"))相同位元組會產生相同摘要;只要內容改變,摘要通常就不同。雜湊適合驗證完整性,但不能從摘要還原檔案。
八、複製後驗證是否一致
def verify_same_file(source, target):
source_hash = sha256_file(source)
target_hash = sha256_file(target)
return {
"來源SHA256": source_hash,
"目標SHA256": target_hash,
"內容一致": source_hash == target_hash,
}
# result = verify_same_file("原始媒體/訪談.wav", "備份/訪談.wav")
# print(result)九、Base64:把位元組轉成文字
import base64
original = b"USR binary demo"
encoded = base64.b64encode(original)
decoded = base64.b64decode(encoded, validate=True)
print(encoded.decode("ascii"))
print(decoded)
print(original == decoded)Base64常用於JSON、電子郵件或文字通道傳輸二進位內容,但體積會增加,而且不是加密。任何拿到內容的人都能解碼,不能用來保護訪談錄音或設備憑證。
十、建立二進位檔清冊
from pathlib import Path
def binary_inventory(folder):
allowed = {".jpg", ".jpeg", ".png", ".wav", ".mp3", ".pdf"}
records = []
for path in sorted(Path(folder).rglob("*")):
if path.is_file() and path.suffix.lower() in allowed:
records.append({
"相對路徑": str(path.relative_to(folder)),
"大小": path.stat().st_size,
"SHA256": sha256_file(path),
})
return records
# for record in binary_inventory("教學媒體"):
# print(record)清冊公開前要檢查檔名是否含姓名、地址或活動參與者資訊。SHA-256摘要本身通常不透露內容,但可用於比對已知檔案,仍應依資料政策管理。
十一、驗證備份清冊
def compare_inventories(source_records, backup_records):
source_map = {
record["相對路徑"]: record["SHA256"]
for record in source_records
}
backup_map = {
record["相對路徑"]: record["SHA256"]
for record in backup_records
}
all_paths = sorted(source_map.keys() | backup_map.keys())
return [
{
"相對路徑": path,
"狀態": (
"一致"
if source_map.get(path) == backup_map.get(path)
else "缺少或內容不同"
),
}
for path in all_paths
]十二、不要用雜湊保存密碼
本篇SHA-256用於檔案完整性,不適合直接保存使用者密碼。密碼需要專用、帶鹽且刻意緩慢的演算法與成熟框架;也不要自己發明加密方式。
十三、常見錯誤檢查表
| 現象 | 原因 | 修正 |
|---|---|---|
| 照片出現UnicodeDecodeError | 以文字模式讀取 | 改用rb,不指定encoding |
| 大型錄音占滿記憶體 | 一次read全部內容 | 使用固定大小分塊 |
| 備份覆蓋原檔 | 使用wb且未檢查 | 使用xb並分開來源與目標 |
| 檔案大小相同就判斷一致 | 大小不能代表內容 | 比較SHA-256 |
| 把Base64當加密 | 誤解其用途 | 視為編碼,不存敏感資料 |
十四、USR實作挑戰
對已授權的教學副本建立相對路徑、大小與SHA-256清冊,檢查檔名是否洩露個資。
複製三個小型教學檔案到獨立資料夾,比對雜湊;再修改副本一個位元組,觀察結果。
為原始錄音、內部研究版、講述者確認版與公開剪輯版設計不同資料夾與存取規則。
十五、與生成式AI協作
請擔任Python二進位檔與USR媒體保存助教。
請檢查我的照片與錄音備份程式:
1. 使用rb與xb,不得覆蓋原始媒體;
2. 大檔案必須分塊處理;
3. 複製後以SHA-256驗證;
4. Base64只能視為編碼,不是加密;
5. 清冊不得洩露不必要個資;
6. 能存取檔案不代表取得公開或AI訓練授權。
請先列出風險,再提供可測試函式。二進位檔要用位元組模式處理,大檔案要分塊,重要副本要拒絕覆蓋並用雜湊驗證。技術確保內容完整,授權與權限制度則確保使用正當。
沒有留言:
張貼留言