世界上的文字能夠被四個字節徹底覆蓋,也就是UTF-32,其餘都是變長的格式。而剛好ARGB加起來四個字節,因而徹底能夠把一個字符映射爲一個像素點嘛!git
而且圖片上的字節能夠再次加密,很是好玩!我僅演示的超級無敵簡單的取反操做。dom
我本身習慣看方形的圖片,因而開平方取整,若是字符數量不足就從字符自己隨機取一段,這是爲了圖片尾部不會幾個像素留白,炒雞不美觀,以白色(0xFFFFFFFF)做爲終止字符。函數
static Bitmap ArgbTextEncode(string input) { var x = 0; var y = 0; var lenth = input.Length; var yValue = (int)(Math.Sqrt(input.Length) + 1); var fill = (yValue * yValue) % (Encoding.Unicode.GetByteCount(input) / 4); input += input.Substring(Rnd.random.Next(input.Length - fill - 1), fill); var image = new Bitmap(yValue, yValue); //fill for (int i = 0; i < yValue * yValue; i++) { if (i == lenth - 1) { image.SetPixel(x, y, Color.White); } else { byte[] bytes = Encoding.Unicode.GetBytes(input[i].ToString()); var prefix = 4 - bytes.Length; bytes = Enumerable.Repeat<byte>(0, prefix).Concat(bytes).ToArray(); Encrypt(bytes); image.SetPixel(x, y, Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3])); } //Console.WriteLine("{0},{1} = {2}", x, y, input[i]); x++; if (x % yValue == 0) { x = 0; y++; } } return image; }
找了一個日誌文本,看看效果加密
解碼函數日誌
static string DecodeTextFromArgb(Bitmap image) { //ComplexImage comp = ComplexImage.FromBitmap(image); //comp.BackwardFourierTransform(); var str = ""; for (int i = 0; i < image.Height; i++) { for (int j = 0; j < image.Width; j++) { var color = image.GetPixel(j, i); if (color.A == 255 && color.R == 255 && color.G == 255 && color.B == 255) return str; var bytes = new byte[] { color.A, color.R, color.G, color.B }; Decrypt(bytes); int skip = 0; if (bytes[0] == 0) { if (bytes[1] == 0) { skip = 2; } else { skip = 1; } } else { skip = 0; } var t = Encoding.Unicode.GetString(bytes.Skip(skip).ToArray()); //Console.WriteLine("{0},{1} = {2}", j, i, t); str += t; } } return str; }
裏面用到的Encrypt和Decrypt是取反的,否則圖片一片漆黑,啥看不見。這句是我剛想到真的用取反操做符來,實際我是用的255去減的。code
unchecked((byte)~(byte)value)
Encrypt和Decrypt,其實同樣的。。哈哈orm
static byte[] Encrypt(byte[] values) { for (int i = 0; i < values.Length; i++) { values[i] = (byte)(255 - values[i]); } return values; } static byte[] Decrypt(byte[] values) { for (int i = 0; i < values.Length; i++) { values[i] = (byte)(255 - values[i]); } return values; }
本程序完整代碼以下:blog
class Program { static void Main(string[] args) { if (!args.Any()) { return; } else if (args[0].EndsWith(".txt", StringComparison.OrdinalIgnoreCase)) { var textRaw = File.ReadAllText(args[0], Encoding.Unicode); var image = ArgbTextEncode(textRaw); var imagePath = Path.ChangeExtension(args[0], ".png"); image.Save(imagePath, ImageFormat.Png); image.Dispose(); Console.WriteLine("TXT->PNG, " + imagePath); try { Process.Start(imagePath); } catch { } } else if (args[0].EndsWith(".png", StringComparison.OrdinalIgnoreCase)) { var image = (Bitmap)Bitmap.FromFile(args[0]); string text = ""; try { text = DecodeTextFromArgb(image); } catch (Exception ex) { Console.WriteLine("PNG->TXT, 轉換失敗"); return; } var txtPath = Path.ChangeExtension(args[0], ".txt"); File.WriteAllText(txtPath, text, Encoding.Unicode); Console.WriteLine("PNG->TXT, " + txtPath); try { Process.Start(txtPath); } catch { } } else { Console.WriteLine("只支持TXT和PNG文件"); } } static Bitmap ArgbTextEncode(string input) { var x = 0; var y = 0; var lenth = input.Length; var yValue = (int)(Math.Sqrt(input.Length) + 1); var fill = (yValue * yValue) % (Encoding.Unicode.GetByteCount(input) / 4); input += input.Substring(Rnd.random.Next(input.Length - fill - 1), fill); var image = new Bitmap(yValue, yValue); //fill for (int i = 0; i < yValue * yValue; i++) { if (i == lenth - 1) { image.SetPixel(x, y, Color.White); } else { byte[] bytes = Encoding.Unicode.GetBytes(input[i].ToString()); var prefix = 4 - bytes.Length; bytes = Enumerable.Repeat<byte>(0, prefix).Concat(bytes).ToArray(); Encrypt(bytes); image.SetPixel(x, y, Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3])); } //Console.WriteLine("{0},{1} = {2}", x, y, input[i]); x++; if (x % yValue == 0) { x = 0; y++; } } return image; } static byte[] Encrypt(byte[] values) { for (int i = 0; i < values.Length; i++) { values[i] = (byte)(255 - values[i]); } return values; } static byte[] Decrypt(byte[] values) { for (int i = 0; i < values.Length; i++) { values[i] = (byte)(255 - values[i]); } return values; } static string DecodeTextFromArgb(Bitmap image) { //ComplexImage comp = ComplexImage.FromBitmap(image); //comp.BackwardFourierTransform(); var str = ""; for (int i = 0; i < image.Height; i++) { for (int j = 0; j < image.Width; j++) { var color = image.GetPixel(j, i); if (color.A == 255 && color.R == 255 && color.G == 255 && color.B == 255) return str; var bytes = new byte[] { color.A, color.R, color.G, color.B }; Decrypt(bytes); int skip = 0; if (bytes[0] == 0) { if (bytes[1] == 0) { skip = 2; } else { skip = 1; } } else { skip = 0; } var t = Encoding.Unicode.GetString(bytes.Skip(skip).ToArray()); //Console.WriteLine("{0},{1} = {2}", j, i, t); str += t; } } return str; } }
源碼地址:https://gitee.com/kstudio/ArgbText圖片