【密码学原理与实践】(一)移位密码 附java代码实现

移位密码(Shift Cipher)

转载请著名出处

密码体制

一个密码体制是满足以下条件的五元组(P,C,K,E,D)

P表示所有可能的明文组成的有限集

C表示所有可能的密文组成的有限集

K表示秘钥空间,由所有可能的密钥组成的有限集

对每一个k∈K,都存在一个加密规则ek∈E和相应的解密规则dk∈D,并且对ek:P->C,dk:C->p,满足条件:对每一个明文x∈P,均有dk(ek(x)))=x

在学习移位密码之前需要了解的是移位密码的基础是数论中的模运算。所以首先来看模运算的基本定义。

模运算

模运算基本定义

假设a和b均为整数,m是一正整数。若m整除b-a,则可将其表示为a = b(mod m),式a=b(mod m)

读作“a与b模m同与”,正整数m称为模数。

假如用m分别除a和b,可得相应的商和余数,余数是在0与m-1之间。即可将a与b分别表示为a=q1m+r1,b=q2m+r2,其中0<=r1<=m-1,0<=r2<=m-1.这样可以看出如果a与b模m同余当且仅当r1=r2。我们使用记号a mod m来表示a除以m所得的余数。因此,a与b模m同余当且仅当a mod m = b mod m 。如果用a mod m来代替a,我们就说a被模m约化了。

简单一句话来说呢就是如果a与b模m同与就是a除以m和b除以m所得的余数相同。

模m上的算术运算

令Zm表示集合{0,1,2,…m-1},在其上定义两个运算,加法(+)和乘法(×)其运算类似与put的实数域上的加法和乘法,所不同的只是所得的值是取模以后的余数。

举个栗子:

在Z16上计算11×13,因为11×13=143 = 8×16+15,故在Z16上11×13=15.

运算法则
  1. 对加法运算封闭:对任意的a,b∈Zm,有a+b属于Zm
  2. 加法运算满足交换律:对任意的a,b∈Zm,有a+b=b+a
  3. 加法运算满足结合律:对任意的a,b,c∈Zm,有(a+b)+c = a+(b+c)
  4. 0是加法单位元:对任意的a属于Zm,有a+0=0+a=a
  5. 任何元素存在加法逆元:a的逆元为m-a,因为a+(m-a)=(m-a)+a=0
  6. 对乘法运算封闭:对任意的a,b属于Zm,有ab∈Zm
  7. 乘法运算满足交换律:对任意的a,b属于Zm,有ab=ba
  8. 乘法运算满足结合律:对任意的a,b,c∈Zm,有(ab)c=a(bc)
  9. 1是乘法单位元:对任意的a属于Zm,有a×1=1×a=a
  10. 乘法和加法之间存在分配律:对任意的a,b,c∈Zm,有(a+b)c=(ac)+(bc),a(b+c)=(ab)+(ac)

移位密码

令P=C=K=Z126,对于0<=K<=25,任意x,y∈Z26,定义ek=(x+K)mod 26 和dk(y)=(y-K)mod 26

建立关系

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

举个栗子

假设移位密码的秘钥为K=11,明文为wewillmeetatmidnight

由上可知ek=(x+11)mod26

首先将明文中的字母对应于其相应的整数,得到如下的数字串:22 4 22 8 11 11 12 4 4 19 0 19 12 8 3 13 8 6 7 19,

原文 w e w i l l m e e t a t m i d n i g h t
对应字母表 22 4 22 8 11 11 12 4 4 19 0 19 12 8 3 13 8 6 7 19
(x+11)mod26 7 15 7 19 22 22 23 15 15 4 11 4 23 19 14 24 19 17 18 4

再参照字母表可得密文串为HPHTWWXPPELEXTOYTRSE

解密同理,使用dk=(y-11)mod26即可,此处就不再详细描述。

缺陷

移位密码是不安全的,可以使用秘钥穷尽搜索方法来破译。

代码实现

package com.slp.cryptography;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName ShiftCipher
 * @Description 移位密码
 * @Author sanglp
 * @Date 2020/11/30 9:26
 * @Version 1.0
 **/
public class ShiftCipher {
    
    
    static int moduleNum = 26;//模数
    /**
     * 移位密码算法
     * @param resource 加密明文
     * @param k k
     */
    public static void enShiftCipher(String resource,int k){
    
    
    //由参数可知加密函数为 (x+K)mod 26
        StringBuilder result = new StringBuilder();
        char [] reschar = resource.toCharArray();
        for(int i=0;i<reschar.length;i++){
    
    
            char temp =reschar[i];
            if(reschar[i] >='a'&&reschar[i]<='z'){
    
    //将输入统一转换为大写数字
                temp = (char) (temp-32);
            }
            result.append((char)((temp-'A'+k)%26+'A'));//这样可以不用再维护字母和数字的关系
        }
        System.out.println(result);
    }

    /**
     * 解密算法
     * @param resource
     * @param k
     */
    public static void deShiftCipher(String resource,int k){
    
    
        //由参数可知解密函数为 (y-K)mod 26
        StringBuilder result = new StringBuilder();
        char [] reschar = resource.toCharArray();
        for(int i=0;i<reschar.length;i++){
    
    
            char temp =reschar[i];
            if(reschar[i] >='a'&&reschar[i]<='z'){
    
    //将输入统一转换为大写数字
                temp = (char) (temp-32);
            }
            result.append((char)((temp-'A'-k)%26<0?(temp-'A'-k+26)%26+'A':(temp-'A'-k)%26+'A'));//这里需要考虑如果余数为负的情况
        }
        System.out.println(result);
    }
    public static void main(String[] args) {
    
    
        enShiftCipher("wewillmeetatmidnight",11) ;
        deShiftCipher("HPHTWWXPPELEXTOYTRSE",11);
        forceDecrypt("HPHTWWXPPELEXTOYTRSE");
    }

    /**
     * 暴力破解
     * @param resource
     */
    public static void forceDecrypt(String resource){
    
    
        for(int i=0;i<26;i++){
    
    
            deShiftCipher(resource,i);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_51656605/article/details/110377659