【密码学】古代、古典密码

【密码学】古代、古典密码古代密码 数据的保密基于加密算法 的保密 Scytale 密码 使用一条纸袋作为载体 环绕在一根固定半径的圆柱上 加密 在绕好的纸带上写上明文 解开缠绕后 就是加密好的 无序的密文 圆柱的半径就是密钥 解密 找到相同大小的圆柱 将纸带缠绕在援助上 即得到密文 棋盘密码 将 26

大家好,我是讯享网,很高兴认识大家。

古代密码

  • 数据的保密基于加密算法的保密。

Scytale密码

  • 使用一条纸袋作为载体,环绕在一根固定半径的圆柱上。

  • 讯享网

加密

  • 在绕好的纸带上写上明文。
  • 解开缠绕后,就是加密好的、无序的密文。
  • 圆柱的半径就是密钥

解密

  • 找到相同大小的圆柱,将纸带缠绕在援助上,即得到密文。

棋盘密码

  • 26个字母放进一个5x5的表格中(ij放在一起)。

加密

  • 将明文对照表格找到横纵坐标,横坐标+纵坐标即为单个字符的密文。
  • 其中这个表格就是密钥

解密

  • 对照表格,将密文以2个数字一组,找到对应的字母。

凯撒密码

  • 是一种移位密码,将字母对应到相应的数字(A对应为0)后,通过循环移位,改变对应的字母。

加密

  • 先将每个字母对应到0~25的数字。
  • 再进行移c位,这里的c就是密钥

c = ( m + k ) % 26 c=(m+k)\%26 c=(m+k)%26

凯撒密码的c3

解密

  • 对移位操作反向执行,即可恢复原文。

m = ( c − k ) % 26 m=(c-k)\%26 m=(ck)%26

古典密码

  • 两种构造方式:
    • 代替密码
    • 置换密码

置换密码

  • 字或者字母本身不变,位置发生改变,形成密文。
  • 又称为易位密码。
  • 下面举出报文倒置法的例子。

加密

  • 将明文倒置输出得到密文。

解密

  • 将密文倒置输出得到明文。

单表代替密码——加法密码

  • 凯撒密码,不多赘述。

加密

  • 代码
//m is message, k is key,l is the length of message void f(int*m, int k,int l){ 
    for(int i=0;i<l;i++){ 
    printf("%c",(m[i]+k)%26+97); } } 

讯享网

解密

  • 代码
讯享网//m is message, k is key,l is the length of message void f(int*c, int k,int l){ 
    for(int i=0;i<l;i++){ 
    printf("%c",(c[i]-k+26)%26+97); } } 

单表代替密码——乘法密码

加密

  • 密钥k26互素,保证k的逆存在。

c = k × m ( m o d 26 ) c=k\times m(mod26) c=k×m(mod26)

  • 代码
//m is message, k is key,l is the length of message void f(int *m,int k,int l){ 
    for(int i = 0;i < l;i++){ 
    printf("%c",m[i]*k%26+97); } } 

解密

  • 利用扩展欧几里得得到k的逆。

m = k − 1 × c ( m o d 26 ) m=k^{-1}\times c(mod26) m=k1×c(mod26)

  • 代码
讯享网int prim[12] = { 
   1,3,5,7,9,11,15,17,19,21,23,25}; //m is message, k is key,l is the length of message void f(int *c,int k,int l){ 
    int d; for(int i = 0;i < 12;i++){ 
    if(k*prim[i]%26 == 1){ 
    d = prim[i]; } } for(int i = 0;i < l;i++){ 
    printf("%c",c[i]*d%26+97); } } 

这里由于集合中素数只有12个,依次枚举即可得到密钥的逆。

int prim[12] = { 
   1,3,5,7,9,11,15,17,19,21,23,25}; //decode with exgcd void exgcd(int a,int b,int*yp){ 
    int x; if(!b){ 
    x = 1; *yp = 0; return; } int x1=0,x2=1,y1=1,y2=0,q,r; while(b>0){ 
    q = a/b; r = a-q*b; x = x2-q*x1; *yp = y2-q*y1; a = b; b = r; x2 = x1; x1 = x; y2 = y1; y1 = *yp; } *yp = y2; } void f(int *c,int k,int l){ 
    int d; exgcd(26,k,&d); for(int i = 0;i < l;i++){ 
    printf("%c",c[i]*d%26+97); } } 

单表代替密码——仿射密码

  • 结合加法密码和乘法密码就得到仿射密码。

加密

c = a × m + b ( m o d 26 ) c=a\times m+b(mod26) c=a×m+b(mod26)

解密

  • 分别使用加法密码和乘法密码的逆过程即可得到。

m = a − 1 ( c − b ) ( m o d 26 ) m=a^{-1}(c-b)(mod26) m=a1(cb)(mod26)

单表代替密码——密钥短语代替

  • 这种密码选用一个英文短语或者单词串作为密钥,称为密钥字或密钥短语

加密

  • 构造乱序字母表作为密钥,将明文中的字符进行映射。
  • 例如下表(一三行为明文表,二四行为对应密文)。
a b c d e f g h i j k l m
H A P Y N E W R B C D F G
n o p q r s t u v w x y z
I J K L M O Q S T U V X Z

解密

  • 得到字母表之后进行一一替换即可。

通过大量密文统计每个字符出现概率,在单一密文里面找到对应概率的字符进行替换尝试,可能导致在没有字母表时密文被激活成功教程。

多表代换密码

  • 每一位字符对应不同的加密方法,构造二维表作为密钥

加密

  • 构造可逆模26互素矩阵,利用它和明文串相乘得到密文串。

C i = A M i + B ( m o d N ) C_i=AM_i+B(mod N) Ci=AMi+B(modN)

  • 由于在构造二维表时,我太懒了难以找到满足条件的表,这里代码只给出3阶密钥(老师给的)。
讯享网int key[NUM][NUM] = { 
   { 
   11,2,19},{ 
   5,23,25},{ 
   20,7,17}}; void f(int *m,int l){ 
    char c; for(int i = 0;i < l;i++){ 
    c = 0; for(int j = 0;j < l;j++){ 
    c += key[i][j]*m[j]%26; } printf("%c",c%26+97); } } 

解密

  • 利用矩阵可逆的条件,构造逆矩阵作为乘法矩阵。
  • 密文串和逆矩阵做乘法之后便得到明文串。

M i = A − 1 ( C i − B ) ( m o d N ) M_i=A^{-1}(C_i-B)(modN) Mi=A1(CiB)(modN)

  • 代码
int dkey[NUM][NUM] = { 
   { 
   10,23,7},{ 
   15,9,22},{ 
   5,9,21}}; void f(int *c,int l){ 
    char m; for(int i = 0;i < NUM;i++){ 
    m = 0; for(int j = 0;j < NUM;j++){ 
    m += dkey[i][j]*c[j]%26; } printf("%c",m%26+97); } } 
  • 代码
讯享网int dkey[NUM][NUM] = { 
   { 
   10,23,7},{ 
   15,9,22},{ 
   5,9,21}}; void f(int *c,int l){ 
    char m; for(int i = 0;i < NUM;i++){ 
    m = 0; for(int j = 0;j < NUM;j++){ 
    m += dkey[i][j]*c[j]%26; } printf("%c",m%26+97); } } 

实际上统一密文以l为单位长度

小讯
上一篇 2025-03-30 14:01
下一篇 2025-03-03 08:45

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/70274.html