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

  • 相关阅读:
    macbook 无声音解决方案
    webapck dev server代理请求 json截断问题
    百度卫星地图开启
    服务器 nginx配置 防止其他域名绑定自己的服务器
    记一次nginx php配置的心路历程
    遇到npm报错read ECONNRESET怎么办
    运行svn tortoiseSvn cleanup 命令失败的解决办法
    svn add 命令 递归目录下所有文件
    m4出现Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread, ungetc on your system, then report this to bug-gnulib."
    Ubuntu下安装GCC,mpc、mpfr、gmp
  • 原文地址:https://www.cnblogs.com/nanqi/p/VisualCrypto.html
Copyright © 2011-2022 走看看