天天看點

加密算法 MD5/SHA1

近來想學習函數式程式設計。

但是一直不知道怎麼展開這個學習過程,目前的研究進度也不深入,想講解一些原理也無從下手。

先簡單的上一些算法,逐漸分析文法和思想。雖然程度不深,但至少能記錄這個過程。

本例子用F#編寫,是一種強類型,非純函數式程式設計語言,在.net平台上運作,實際上為了相容.net平台,你可以使用各種.net的基本類型和庫。

C#的測試結果,從結果上看沒有問題。

F#源碼

1 namespace Heron.Helpers
 2 
 3 open System.Text
 4 open System.Security.Cryptography
 5 
 6 module Encrypt =
 7     let Sha1Hash (str : string) = 
 8         let sha1 = SHA1.Create ()
 9         let sha1arr = sha1.ComputeHash (Encoding.UTF8.GetBytes (str))
10         let sha1str = String.concat "" (Array.init 20 (fun i -> sprintf "%02x" sha1arr.[i]))
11         sha1str
12 
13     let Md5Hash (str : string) =
14         let md5 = MD5.Create ()
15         let md5arr = md5.ComputeHash (Encoding.UTF8.GetBytes (str))
16         let md5str = String.concat "" (Array.init 16 (fun i -> sprintf "%02x" md5arr.[i]))
17         md5str      

短短數行就完成,是不是很簡潔呢。

namespace Heron.Helpers

open System.Text
open System.Security.Cryptography

/// 這段不用多說,namespace和C#中的功能一樣,聲明命名空間。
/// open相當于using ,導入一個命名空間      
module Encrypt =
/// 這裡的module是用來區分個子產品功能的,對程式意義不大,在C#裡被當作一個靜态類處理相容。F#是縮進敏感的語言,縮進比這段語句多一層的都屬于這個子產品下面的。是以下面的兩個函數可以了解為這個子產品的靜态方法。      
let Sha1Hash (str : string) = 
    let sha1 = SHA1.Create ()
    let sha1arr = sha1.ComputeHash (Encoding.UTF8.GetBytes (str))
    let sha1str = String.concat "" (Array.init 20 (fun i -> sprintf "%02x" sha1arr.[i]))
    sha1str

/// let是用來綁定一個辨別符,可以是實數,可以是字元串,可以是對象,也可以是函數,這裡綁定的就是一個函數,帶有一個string類型的參數str,最後一行為傳回值,這裡就是傳回sha1str這個辨別。實際上純函數語言裡是沒有變量的,也沒有基本類型,所有的東西都是函數,比如 let a = 0,你可以了解為沒有參數,傳回int的函數。F#為了相容.net平台,類型都是靜态綁定,靠自動推算來得到類型。
/// 這裡用到的F#特性不多,隻有第4行用到一點。可能看起來有點暈,我們來分解一下
Array.init 20 (fun i -> sprintf "%02x" sha1arr.[i])
/// Array.init 這是一個函數,有兩個參數,第一個表示傳回的數組個數,第二個參數為一個匿名函數,就是括号裡的内容(fun i -> sprintf "%02x" sha1arr.[i])。這個函數會疊代i 從0到19 剛好對應sha1arr的下标,然後一次轉為16進制的數表示,不足的前面補零。
String.concat "" Array
/// 這個是把一個數組元素拼接為一個字元串的函數,第一個參數是拼接的符号,這裡是空字元串,第二個參數是數組,就是上面生成的20個16進制的數。
/// 是不是代碼簡潔了很多呢      

以後可能會陸續帶來參數函數,傳回值函數等高階函數和泛型的随筆。不過我還是希望從實際資料着手,要有實際應用的空間。因為現在掌握的也不深,也沒多少東西賣弄。

以後我會慢慢收集各種實用的算法,然後形成一個工具包,等實用度達到一定基礎後會釋出出來。不知道大家看好不。

如果大家有對函數程式設計的獨特見解,也歡迎留言讨論。