Hash Function 的結果會是一個數字,除了稱它們為 Hash 值外,我們也常稱它們為 Digest,不是消化喔,翻成摘要比較適當。因為你輸入一篇文章到 Hash Function 裡,會生成一個獨一無二的值,好像代表了那篇文章一樣。
總之Digest 就是 Hash 的結果。
為了對應到的數字要盡量不碰撞,那 Digest 的數字的集合一定要夠大,是吧?如果 Hash Function 只對應到 0 - 9,那我們幾本上可以說當我輸入第 11 個輸入時,必有碰撞產生,這叫鴿籠原理嘛!(太抽象了嗎?或是我說如果你交了十二任女友,每一個星座都不同,那我斷定你第十三任女友的星座必會與前任同複!)
所以實務上 Hash Function 通常產生很是很大的數字,又因為電腦都是用 2 進位,數字都是 0 與 1 的 bit,因為用了很多個 bit,所以也可以說是很長的數字。例如
111111101010101010011110100101010101001010
但這樣的表示法第一很沒意義,第二很長不方便比較。
那我們可以改用 Base64 或 Hex(16進位) 的方式來表示。16進位表示法就是每4-bit轉成 0..9 及 A..F,請自行查一下 wiki。我們下面介紹 Base64 表示法。
Base64 僅是一種表示資料的方式,因為最後的結果是一串亂碼,容易被誤會是資料加密,其實是完全沒有關係。
Base64 可以想成「用 64 種字元」去代表任何資料。
因為電腦的資料不論如何,一定是 0 跟 1 的組合,
以 6 個 2進位為一組,會有64種組合,給每種組合一個代表的「字元 Char」,可以用那64種字元去代表所有的字串了
就如同下表:
以 Wiki 上的例子Man
轉成 Base64 來說, ascii 是用 8 bits 存的,所以 共有 24 bits
T
,然後剩 2 bit 01
W
TWFu
=
去代替我們可以用這個方式拆解中文我
試看看:
https://onlineutf8tools.com/convert-utf8-to-binary 線上工具轉 UTF-8 至 Binary
我剛好是3個 byte,24bits 所以用 base64 恰好是 4個字元顯示
puts Base64.encode64 '我'
# 5oiR
# 注意decode base64時,它不知道那是 utf-8 所以要自己轉回去
Base64.decode64('5oiR')
# "\xE6\x88\x91"
Base64.decode64('5oiR').encoding
# #<Encoding:ASCII-8BIT>
Base64.decode64('5oiR').force_encoding('UTF-8')
# "我"
有些不是「文字」的檔案,比如說圖片檔,依然可以以 0跟 1表示
所以一張圖可以寫成超長的011010101010....的字串,所以稱它們為 Binary data。
在傳送檔案時,就可以用 base64 去表示任何檔案。
希望有幫助到大家理解喔