古典密码实验
古典密码编码方法归根结底主要有两种,即置换和代换。
把明文中的字母重新排列,字母本身不变,但其位置改变了,这样编成的密码称为置换密码。最简单的置换密码是把明文中的字母顺序倒过来,然后截成固定长度的字母组作为密文。
代换密码则是将明文中的字符替代成其他字符。
代替密码体制
加密:(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();
}

