古典密码实验
古典密码编码方法归根结底主要有两种,即置换和代换。
把明文中的字母重新排列,字母本身不变,但其位置改变了,这样编成的密码称为置换密码。最简单的置换密码是把明文中的字母顺序倒过来,然后截成固定长度的字母组作为密文。
代换密码则是将明文中的字符替代成其他字符。
代替密码体制
加密:(p) = p + k ( mod 26 ) = c ∈ C
解密: p = (c) = c - k ( mod 26 )
例: 明文 China → 2 7 8 13 0
k = 3 Caesar(凯撒)密码
明文 密文
C : = 2 + 3 ( mod 26 ) = 5 F
h : = 7 + 3 ( mod 26 ) = 10 K
i : = 8 + 3 ( mod 26 ) = 11 L
n : = 13 + 3 ( mod 26 ) = 16 Q
a : = 0 + 3 ( mod 26 ) = 3 D
/* * 函数名称ECaesar(char ch, int k) * 功能:凯撒密码加密实例 * char ch 传递需要加密的字符 * int k 密匙 */ static int ECaesar(char ch, int k) { //统一大写字符输出 if(ch >= 'A' && ch <= 'Z') return (ch - 'A' + 26 + k % 26)%26 + 'A'; else return (ch - 'a' + k % 26)%26 + 'A'; } /* * 函数名称DCaesar(char ch, int k) * 功能:凯撒密码解密实例 * char ch 传递需要解密的字符 * int k 密匙 */ static int DCaesar(char ch, int k) { //统一大写字符输出 if (ch >= 'A' && ch <= 'Z') return (ch - 'A' + 26 - k % 26) % 26 + 'A'; else return (ch - 'a' - k % 26) % 26 + 'A'; }
代替密码的实现方法分类
1).单表代替密码
①使用秘钥的单表对照加密
②仿射密码
是一个线性变换
加密 :
解密:
要求:
/* * 函数名称EAffine(char ch, int k1, int k2) * 功能:仿射密码加密实例 * char ch 传递需要加密的字符 * int k1 秘钥1 * int k2 秘钥2 */ static int EAffine(char ch, int k1, int k2) { //统一大写字符输出 if (ch >= 'A' && ch <= 'Z') return ((ch - 'A') * k1 + k2 + 26) % 26 + 'A'; else return ((ch - 'a') * k1 + k2) % 26 + 'A'; } /* * 函数名称EAffine(char ch, int k1, int k2) * 功能:仿射密码解密实例 * char ch 传递需要解密的字符 * int k1 秘钥k1的逆元 * int k2 秘钥2 */ static int DAffine(char ch, int k1, int k2) { //统一大写字符输出 if (ch >= 'A' && ch <= 'Z') return ((ch - 'A' - k2 + 26) * k1) % 26 + 'A'; else return ((ch - 'a' - k2) * k1) % 26 + 'A'; } /* * 函数名称Determiningprimenum(int k1) * 功能:仿射密码对秘钥k1进行素性检验 * int k1 秘钥1 */ static Boolean Determiningprimenum(int k1) { int i; for (i = 2; i < k1; i++) if (k1 % i == 0) return true; return false; } /* * 函数名称GetInverse(int k1) * 功能:仿射密码对秘钥k1求逆元 * int k1 秘钥1 */ static int GetInverse(int k1) { int i; for(i=2; ; i++) { if ((i * k1) % 26 == 1) { break; } } return i; }
主函数:
static void Main(string[] args) { string Plaintext; //明文 string Ciphertext = null;//密文 int k1, k2;//密匙对 Console.WriteLine("凯撒密码加解密实例"); // 输出内容到控制台 Console.WriteLine("请输入明文:"); // 接收用户输入,为变量赋值 Plaintext = Console.ReadLine(); Console.WriteLine("请输入秘钥:"); //接受控制台的输入内容,强制转换为整形 k1 = int.Parse(Console.ReadLine()) ; Console.Write("加密后密文:"); for (int i = 0; i < Plaintext.Length; i++) { Ciphertext += (char)ECaesar(Plaintext[i], k1); Console.Write((char)ECaesar(Plaintext[i], k1)); } Console.WriteLine(); Console.Write("解密后明文:"); for (int i = 0; i < Ciphertext.Length; i++) { Console.Write((char)DCaesar(Ciphertext[i], k1)); } Ciphertext = null; Console.WriteLine(); Console.WriteLine("仿射密码加解密实例"); // 输出内容到控制台 Console.WriteLine("请输入明文:"); // 接收用户输入,为变量赋值 Plaintext = Console.ReadLine(); do { Console.WriteLine("请输入秘钥k1:"); //接受控制台的输入内容,强制转换为整形 k1 = int.Parse(Console.ReadLine()) % 26; } while (Determiningprimenum(k1)==true); Console.WriteLine("请输入秘钥k2:"); //接受控制台的输入内容,强制转换为整形 k2 = int.Parse(Console.ReadLine()); Console.Write("加密后密文:"); for (int i = 0; i < Plaintext.Length; i++) { Ciphertext += (char)EAffine(Plaintext[i], k1, k2); Console.Write((char)EAffine(Plaintext[i], k1, k2)); } Console.WriteLine(); //获取秘钥k1的逆元 int k = GetInverse(k1); Console.Write("解密后明文:"); for (int i = 0; i < Ciphertext.Length; i++) { Console.Write((char)DAffine(Ciphertext[i], k, k2)); } //避免闪屏退出 Console.ReadKey(); }