跳至主要內容
全球國際徵信顧問
案件指揮艙全部本機工具
V235 / OPERATING GUIDE

先讀範圍,再決定帳本能替你做什麼。

證據鏈帳本與 QR 交接碼都只在你的瀏覽器內處理,不上傳檔案、不使用瀏覽器儲存空間。本頁說明做什麼、不做什麼、規則細節、如何自行驗證,以及最常被誤解的地方。

READ FIRST

先說清楚這不是什麼

這不是可信時間戳,不是公證,也不證明檔案內容真實或檔案何時產生。
LEDGER / HASH CHAIN

證據鏈帳本

為多個本機檔案逐一計算 SHA-256,把每一筆接在前一筆的鏈雜湊之後,並計算整份帳本的 Merkle 根。

做什麼
  • 加入多個檔案(帳本至多 500 筆、單檔上限 512 MiB)。檔案以 File.slice 每 4 MiB 分塊讀取,在背景 Worker 內以自行實作的增量 SHA-256 計算,不整檔載入、不阻塞畫面,可隨時取消。
  • 每筆記錄序號、檔名、大小、檔案宣告的最後修改時間、SHA-256、備註(至多 200 字)、加入時間(裝置時鐘)、前一筆的鏈雜湊 prev,以及本筆鏈雜湊 entryHash。
  • 顯示鏈尾 headHash 與 Merkle 根,並以前 16 碼分組顯示成「封存碼」,完整值可展開複製。
  • 匯出 JSON(格式 gib-ledger-1,內含引擎版本與規範化規則)、CSV 與人可讀的 TXT 收據。
  • 匯入 JSON 時完整驗證:重算每筆鏈雜湊、鏈接與 Merkle 根,指出最早不符的位置與原因;可另外填入你保存的封存碼比對。驗證通過後可接續追加。
  • 「再核對檔案」:重新選取檔案,依檔名與 SHA-256 配對,列出相符、雜湊不符、缺少、僅檔名不同與未收錄,不更動帳本。
不做什麼
  • 不上傳、不聯網、不使用任何瀏覽器儲存空間(含 cookie);關閉或重新整理頁面,畫面上的帳本即消失。
  • 不提供修改或刪除單筆;只能追加、整本重建或「清除全部」。
  • 不取得第三方時間戳,不連到任何區塊鏈或公證服務。
  • 不判斷檔案是否真實、是否被編修,也不辨識內容。
規則細節
  • 鏈雜湊:entryHash = SHA-256(UTF-8(規範化 JSON))。規範化 JSON 只含 seq、name、size、mtime、sha256、note、addedAt、prev 八個欄位;鍵依 UTF-16 碼元順序排序;無任何空白;字串依 RFC 8259 最小逸出(同 ECMAScript 的 JSON.stringify,非 ASCII 字元不逸出);數字為十進位整數。創世 prev 為 64 個 0。mtime 為毫秒;addedAt 為 ISO 8601 UTC 毫秒格式。
  • Merkle 根:葉子是各筆 entryHash 的 32 位元組原值;每層若為奇數個就複製末葉補齊;父節點 = SHA-256(左 || 右);空帳本為 64 個 0;只有一筆時,根等於該筆的 entryHash。
  • 鏈尾 headHash:最後一筆的 entryHash。它與 Merkle 根並列,一起構成封存碼。
  • 前 16 碼只供人工核對與口頭確認;它是 64 位元,不足以抵擋有心人刻意製造相同前綴。要比對是否被整本重建,請保存完整的 64 位十六進位值。
如何自行驗證
  • 用作業系統的 sha256sum(或 shasum -a 256、certutil -hashfile)對原檔計算,與帳本中的 SHA-256 比對。
  • 用任何語言重算鏈。下面的 Python 範例讀取匯出的 JSON,不依賴本站任何程式:
import json, hashlib
L = json.load(open("evidence-ledger.json", encoding="utf-8"))
def canon(o):
    return json.dumps(o, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
prev = "0" * 64
for e in L["entries"]:
    body = {k: e[k] for k in ("seq", "name", "size", "mtime", "sha256", "note", "addedAt", "prev")}
    h = hashlib.sha256(canon(body).encode("utf-8")).hexdigest()
    assert e["prev"] == prev and e["entryHash"] == h, e["seq"]
    prev = h
level = [bytes.fromhex(e["entryHash"]) for e in L["entries"]]
while len(level) > 1:
    if len(level) % 2: level.append(level[-1])
    level = [hashlib.sha256(level[i] + level[i + 1]).digest() for i in range(0, len(level), 2)]
print("head", prev, "root", level[0].hex() if level else "0" * 64)
  • 把你保存的封存碼,與這段程式印出的 head 與 root 比對。
常見誤解
  • 「驗證通過」只代表帳本內部一致、沒有自相矛盾;不代表它沒有被整本重建,更不代表檔案真實。
  • 前 16 碼相同不等於整份相同;有爭議時請比對完整值。
  • 備註與檔名會寫進匯出檔,分享前請自行檢查是否含個資。
  • CSV 中以 = + - @ 開頭的儲存格會在前面加一個單引號,避免試算表把它當成公式;JSON 不做這個處理,JSON 才是用來驗證的版本。
  • 檔名相同、內容不同的檔案會顯示為「雜湊不符」,原因無法由雜湊判斷。
開啟這項工具
QR / HANDOFF

QR 交接碼

把短文字轉成 QR 碼,從電腦帶到手機。編碼器在本機執行。

做什麼
  • byte 模式(UTF-8),錯誤更正等級 L/M/Q/H 可選,版本 1 至 25 自動選擇最小版本,含 Reed–Solomon、八種遮罩評分與格式、版本資訊。
  • 輸出 SVG 與 PNG(含 4 個模組寬的靜區,可選每模組像素數),畫面以 SVG 預覽。
  • 可一鍵填入帳本封存碼、LINE 官方帳號連結與電話作為範例。
不做什麼
  • 不加密。QR 的內容是明文,任何人掃了都看得到;不要把個資或案情放進會公開張貼的 QR。
  • 輸入至多 1000 字元;超出所選等級在版本 25 的容量時會明確報錯,不會悄悄截斷。
  • 不產生動態碼,不縮短網址,不經任何伺服器。
如何自行驗證
  • 用手機相機實際掃描,確認文字與你輸入的一致,再交給別人。
  • 以不同等級各產生一次,確認容量與版本變化合理:等級越高,同樣內容的版本越大。
常見誤解
  • 等級 H 不是「更安全」,只是更耐髒污或破損;內容仍是明文。
  • 能被某支手機掃描,不代表所有掃描程式都能;中文以 UTF-8 位元組編碼且不含 ECI 標頭,個別程式可能需要自行指定編碼。
  • 列印尺寸太小、低對比或反光都會影響掃描,請放大後再測。
開啟這項工具

建議的使用流程

  1. 保留原始檔案,不要修改它;帳本記錄的是你按下「加入」當下那份檔案的位元組。
  2. 加入檔案並填備註,記下檔案是從哪裡、何時取得(備註是你自己的說明,不是第三方證明)。
  3. 匯出 JSON 與 TXT 收據,存放在與原檔不同的位置。
  4. 立刻把封存碼交給第三方保存:寄到自己的信箱、交給律師,或傳到 LINE 訊息。可用 QR 把封存碼帶到手機。
  5. 日後需要時,匯入 JSON 驗證,並填入你保存的封存碼比對;再用「再核對檔案」確認手上的檔案仍與帳本一致。
  6. 是否可作為證據、怎麼提出,請諮詢律師。