视觉密码(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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?