視覺密碼(VisualCrypto)

來源:互聯網
上載者:User

先看:

將其中一個圖更改透明度為50%,重疊兩張圖後:

源於:http://leemon.com/crypto/VisualCrypto.html

 

大家可以先去看看,作者的意思是,甲乙兩方需要傳遞訊息,可以事先說好密鑰,傳遞訊息時只要給其發送stream(明文)圖片即可,另一方解密,只需輸入密鑰和相應的訊息長度(輸入等量空格)即可得到ciphertext(密鑰)圖片,最終得到訊息內容。同一張密鑰圖片可以匹配多張明文。

 

原理很簡單,作者根據所給口令(PASSPHRASE),使用和兩張圖片組成了一個圖片,這張圖片只與口令有關。然後對於加密內容,不需要替換的地方使用相反的圖片,需要替換的使用原本的圖片,這樣兩張圖片相疊就能達到需要的效果。

 

暫不討論此等加密的好壞,僅看到作者在最後那一串font的Array就讓我感歎。

 

閑來無事,也想自己寫個支援中文的,於是就有了C#版的VisualCrypto

由於其中使用了caozhy的字模點陣提取程式:

參見:http://topic.csdn.net/u/20120629/17/a33f88b5-7ee8-4a0c-8915-c0c721bb30c9.html

 

 

源碼也已上傳:http://files.cnblogs.com/nanqi/VisualCryptography.zip

 

個人思路

首先將和使用私人欄位_unit代替

bool[][] _unit = new bool[][] { new bool[] { true, false, false, true }, new bool[] { false, true, true, false } };

 

將使用者輸入的口令處理為bool[256] dataCode即16*16的矩陣。

為true則使用第一個,為false使用第二個。最後得到bool[1024] _resultCode即32*32的矩陣。

 

通過字模點陣擷取bool[256] dataMsg即16*16的矩陣。

 

與口令擷取的bool[256] dataCode進行對比產生bool[256] dataDiff,dataMsg中為false的對dataCode取反,為true的不變。

與獲得resultCode方式相同,使用dataDiff獲得相應的_resultMsg。

 

畫出兩張圖。

 

具體代碼

 1 //密碼 2 byte[] code = System.Text.Encoding.Default.GetBytes(textBox1.Text.Trim()); 3  4 if (code.Length == 0) 5 { 6    code = DEF_CODE; 7 } 8 else if (code.Length > 16) 9 {10    code = code.Take(16).ToArray();11 }12 else13 {14    while (code.Length < 4)15    {16       code = code.Concat(code).ToArray();17    }18 }19 20 code = code.Concat(DEF_CODE.Skip(code.Length)).ToArray();21 22 IEnumerable<byte> tmpDataCode = Enumerable.Empty<byte>();23 24 for (int i = 0; i < code.Length; i += 4)25 {26    tmpDataCode = tmpDataCode.Concat(SHA512Encrypt(code.Where((by, index) => (index & 3) == (i / 4 & 3)).ToArray()));27 }28 29 bool[] dataCode = tmpDataCode.Select(by => Convert.ToBoolean(by & 1)).ToArray();

 

//字模Bitmap bmp = new Bitmap(16, 16);Graphics g = Graphics.FromImage(bmp);g.FillRectangle(Brushes.White, new Rectangle() { X = 0, Y = 0, Height = 16, Width = 16 });g.DrawString(textBox2.Text, textBox2.Font, Brushes.Black, Point.Empty);bool[] dataMsg = Enumerable.Range(0, 256).Select(a => new { x = a % 16, y = a / 16 }).Select(x => bmp.GetPixel(x.x, x.y).GetBrightness() > 0.5f ? false : true).ToArray();

 

 1 //差異 2 bool[] dataDiff = dataCode.ToArray(); 3  4 if (dataMsg.Length == dataCode.Length) 5 { 6    for (int i = 0; i < dataMsg.Length; i++) 7    { 8       dataDiff[i] = dataMsg[i] ? dataDiff[i] : !dataDiff[i]; 9    }10 }11 12 //密匙13 IEnumerable<bool> tmpResultCode = Enumerable.Empty<bool>();14 15 foreach (var item in dataCode)16 {17    tmpResultCode = tmpResultCode.Concat(_unit[Convert.ToInt32(item)]);18 }19 20 _resultCode = tmpResultCode.ToArray();21 22 23 //訊息24 IEnumerable<bool> tmpResultMsg = Enumerable.Empty<bool>();25 26 foreach (var item in dataDiff)27 {28    tmpResultMsg = tmpResultMsg.Concat(_unit[Convert.ToInt32(item)]);29 }

 

void Draw(Graphics g, bool[] data){   for (int i = 0; i < 16; i++)   for (int j = 0; j < 16; j++)   for (int k = 0; k < 4; k++)   {      Brush brush = data[j * 4 * 16 + i * 4 + k] ? Brushes.Black : Brushes.White;      if (k < 2)         g.FillRectangle(brush, new Rectangle() { X = i * 16 + k * 8, Y = j * 16, Width = 8, Height = 8 });      else         g.FillRectangle(brush, new Rectangle() { X = i * 16 + (k - 2) * 8, Y = j * 16 + 8, Width = 8, Height = 8 });   }}

 

源於:http://leemon.com/crypto/VisualCrypto.html

參見:http://topic.csdn.net/u/20120629/17/a33f88b5-7ee8-4a0c-8915-c0c721bb30c9.html

源碼:http://files.cnblogs.com/nanqi/VisualCryptography.zip

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.