zoukankan      html  css  js  c++  java
  • 视觉密码(VisualCrypto)

    先看效果图:

    将其中一个图更改透明度为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

    源码也已上传:https://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 else
    13 {
    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

    源码:https://files.cnblogs.com/nanqi/VisualCryptography.zip

  • 相关阅读:
    使用Linq to Sqlite 出现异常Object already attached
    CSS 嵌套DIV布局
    《面试笔记》——MySQL终结篇(30问与答)
    PotPlayer播放器下载
    博客圆的RSS怎么不能用呢
    OPC在自控系统的应用
    TAPI的使用
    刷iPAQ为Linux(zz HiPDA)
    再论软工
    Silverlight的大小自适应中存在的一个问题
  • 原文地址:https://www.cnblogs.com/nanqi/p/VisualCrypto.html
Copyright © 2011-2022 走看看