常用哈希演算法
公鑰加密演算法 也叫非對稱加密,它在加密和解密時使用的是不同的密鑰,具有這樣的特徵:
最常見的公鑰加密演算法是RSA公鑰加密演算法,也是簽名中普遍使用的演算法。其數學原理如下:
理論上 {n, e} 和 {n, d} 可以互換,任何一個都可以是公鑰陸激皮或者私鑰,加密和早差解密的函數也可以互換。但實踐中,一般固定設置 e = 65537(0x10001) ,相當於公開的一個約定,這樣一來 {n, e} 就只能作為公鑰使用。
哈希演算法
也叫散列或者摘要演算法,對一段任意長度的數據,通過一定的映射和計算,得到一個固定長度的值,這個值就被稱為這段數據的哈希值鉛銷(hash)。給定一個哈希演算法,它一定具有以下特徵:
常見的哈希演算法有: md5, sha1, sha256等,其中sha1長度為160bits,而sha256長度為256bits,二者相比,sha256的取值范圍更大,因此碰撞和破解的概率更低,也就相對更安全。
2. 區塊鏈技術中的哈希演算法是什麼
1.1. 簡介
計算機行業從業者對哈希這個詞應該非常熟悉,哈希能夠實現數據從一個維度向另一個維度的映射,通常使用哈希函數實現這種映射。通常業界使用y = hash(x)的方式進行表示,該哈希函數實現對x進行運算計算出一個哈希值y。
區塊鏈中哈希函數特性:
函數參數為string類型;
固定大小輸出;
計算高效;
collision-free 即沖突概率小:x != y => hash(x) != hash(y)
隱藏原始信息:例如區塊鏈中各個節點之間對交易的驗證只需要驗證交易的信息熵,而不需要對原始信息進行比對,節點間不需要傳輸交易的原始數據只傳輸交易的哈希即可,常見演算法有SHA系列和MD5等演算法
1.2. 哈希的用法
哈希在區塊鏈中用處廣泛,其一我們稱之為哈希指針(Hash Pointer)
哈希指針是指該變數的值是通過實際數據計算出來的且指向實際的數據所在位置,即其既可以表示實際數據內容又可以表示實際數據的存儲位置。下圖為Hash Pointer的示意圖
3. 數據結構哈希演算法
1,直接定址法:
函數公式:f(key)=a*key+b (a,b為常數)
這種方法的優點是:簡單,均勻,不會產生沖突。但是需要事先知道關鍵字的分布情況,適合查找表較小並且連續的情況。
2,數字分析法:
比如我們的11位手機號碼「136XXXX7887」,其中前三位是接入號,一般對應不同運營公司的子品牌,如130是聯通如意通,136是移動神州行,153是電信等。中間四們是HLR識別號,表示用戶歸屬地。最後四們才是真正的用戶號。
若我們現在要存儲某家公司員工登記表,如果用手機號碼作為關鍵字,那麼極有可能前7位都是相同的,所以我們選擇後面的四們作為哈希地址就是不錯的選擇。
3,平方取中法:
故名思義,比如關鍵字是1234,那麼它的平方就是1522756,再抽取中間的3位就是227作為哈希地址。
4,折疊法:
折疊法是將關鍵字從左到右分割成位數相等的幾個部分(最後一部分位數不夠可以短些),然後將這幾部分疊加求和,並按哈希表表長,取後幾位作為哈希地址。
比如我們的關鍵字是9876543210,哈希表表長三位,我們將它分為四組,987|654|321|0 ,然後將它們疊加求和987+654+321+0=1962,再求後3位即得到哈希地址為962,哈哈,是不是很有意思。
5,除留余數法:
函數公式:f(key)=key mod p (p<=m)m為哈希表表長。
這種方法是最常用的哈希函數構造方法。
6,隨機數法:
函數公式:f(key)= random(key)。
這里random是隨機函數,當關鍵字的長度不等是,採用這種方法比較合適。
兩種哈希函數沖突解決方法:
我們設計得最好的哈希函數也不可能完全避免沖突,當我們在使用哈希函數後發現兩個關鍵字key1!=key2,但是卻有f(key1)=f(key2),即發生沖突。
4. 1. Crypto 加密演算法
Hash,音譯為哈希,也叫散列函數、摘要演算法。它是把任意長度的輸入,通過散列演算法變換成固定長度的輸出,該輸出就是散列值。
常用的哈希演算法有:
MD5 信息摘要演算法 (MD5 Message-Digest Algorithm),一種被廣泛使用的密碼散列函數,可以產生出一個128位(16位元組)的散列值,用於確保信息傳輸完整一致。
SHA (Secure Hash Algorithm),即安全散列演算法。散列演算法又稱雜湊演算法或哈希演算法,能將一定長度的消息計算出固定長度的字元串(又稱消息摘要)。SHA包含5個演算法,分別是SHA-1、SHA-224、SHA-256、SHA-384和SHA-512,後四者並稱為SHA-2。
循環冗餘校驗 (Cyclic rendancy check,通稱「 CRC 」)是一種根據網路數據包或電腦文件等數據產生簡短固定位數校驗碼的一種散列函數,主要用來檢測或校驗數據傳輸或者保存後可能出現的錯誤。生成的數字在傳輸或者存儲之前計算出來並且附加到數據後面,然後接收方進行檢驗確定數據是否發生變化。一般來說,循環冗餘校驗的值都是32位的整數。
AES ,高級加密標准(Advanced Encryption Standard),又稱 Rijndael 加密法,是美國聯邦政府採用的一種區塊加密標准。
MAC ,消息認證碼(帶密鑰的 Hash 函數):密碼學中,通信實體雙方使用的一種驗證機制,保證消息數據完整性的一種工具。構造方法由 M.Bellare 提出,安全性依賴於 Hash 函數,故也稱帶密鑰的 Hash 函數。消息認證碼是基於密鑰和消息摘要所獲得的一個值,可用於數據源發認證和完整性校驗。
PBKDF2 (Password-Based Key Derivation Function)是一個用來導出密鑰的函數,常用於生成加密的密碼。它的基本原理是通過一個偽隨機函數(例如 HMAC 函數),把明文和一個鹽值作為輸入參數,然後重復進行運算,並最終產生密鑰。如果重復的次數足夠大,破解的成本就會變得很高。而鹽值的添加也會增加「彩虹表」攻擊的難度。
在需要使用 CryptoSwift 的地方將其 import 進來:
歡迎留言討論,有錯誤請指出,謝謝!
Swift 開發學習交流,聯系我 QQ:3500229193 入群,請備注「Swift 學習」!
5. 常見的哈希演算法有哪些
1、RSHash
unsigned int RSHash(const std::string& str)
{
unsigned int b = 378551;
unsigned int a = 63689;
unsigned int hash = 0;
for(std::size_t i = 0; i < str.length(); i++)
{
hash = hash * a + str[i];
a = a * b;
}
return hash;
}
2、JSHash
unsigned int JSHash(const std::string& str)
{
unsigned int hash = 1315423911;
for(std::size_t i = 0; i < str.length(); i++)
{
hash ^= ((hash << 5) + str[i] + (hash >> 2));
}
return hash;
}
3、PJWHash
unsigned int PJWHash(const std::string& str)
{
unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);
unsigned int ThreeQuarters = (unsigned int)((BitsInUnsignedInt * 3) / 4);
unsigned int OneEighth = (unsigned int)(BitsInUnsignedInt / 8);
unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
unsigned int hash = 0;
unsigned int test = 0;
for(std::size_t i = 0; i < str.length(); i++)
{
hash = (hash << OneEighth) + str[i];
if((test = hash & HighBits) != 0)
{
hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));
}
}
return hash;
}
4、ELFHash
unsigned int ELFHash(const std::string& str)
{
unsigned int hash = 0;
unsigned int x = 0;
for(std::size_t i = 0; i < str.length(); i++)
{
hash = (hash << 4) + str[i];
if((x = hash & 0xF0000000L) != 0)
{
hash ^= (x >> 24);
}
hash &= ~x;
}
return hash;
}
5、BKDRHash
unsigned int BKDRHash(const std::string& str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
for(std::size_t i = 0; i < str.length(); i++)
{
hash = (hash * seed) + str[i];
}
return hash;
}
哈希演算法將任意長度的二進制值映射為較短的固定長度的二進制值,這個小的二進制值稱為哈希值。哈希值是一段數據唯一且極其緊湊的數值表示形式。如果散列一段明文而且哪怕只更改該段落的一個字母,隨後的哈希都將產生不同的值。要找到散列為同一個值的兩個不同的輸入,在計算上是不可能的,所以數據的哈希值可以檢驗數據的完整性。一般用於快速查找和加密演算法。
6. 哈希演算法
1.通過哈希值不能反向推導出原始數據(所以哈希演算法也叫單向哈希演算法)
2.對於輸入數據非常敏感,及時更改了一個比特位,哈希值也大不相同
3.散列沖突的概率要小,
4.執行效率要高,及時很長的文本,也能盡快計算出哈希值
MD5的結果是128位 --> 32個16進制串
最常用於加密的哈希演算法是 MD5(MD5 Message-Digest Algorithm,MD5 消息摘要演算法)和 SHA(Secure Hash Algorithm,安全散列演算法)
通過拿到加密後的密文然後再字典表(彩虹表)中比對,找到相同的密文則可以知道其明文。
可以通過在用戶的密碼後加鹽(加入一個字元串)然後加密存儲起來。
區塊鏈是一塊塊區塊組成的,每個區塊分為兩部分:區塊頭和區塊體。
區塊頭保存著 自己區塊體 和 上一個區塊頭 的哈希值。
因為這種鏈式關系和哈希值的唯一性,只要區塊鏈上任意一個區塊被修改過,後面所有區塊保存的哈希值就不對了。
區塊鏈使用的是 SHA256 哈希演算法,計算哈希值非常耗時,如果要篡改一個區塊,就必須重新計算該區塊後面所有的區塊的哈希值,短時間內幾乎不可能做到。
假設我們有 k 個機器,數據的哈希值的范圍是 [0, MAX]。我們將整個范圍劃分成 m 個小區間(m 遠大於 k),每個機器負責 m/k 個小區間。當有新機器加入的時候,我們就將某幾個小區間的數據,從原來的機器中搬移到新的機器中。這樣,既不用全部重新哈希、搬移數據,也保持了各個機器上數據數量的均衡。