[Principles and Practice of Cryptography] (3) Implementation of Affine Ciphers in Java Code

Affine Cipher

Please reprint the source

Affine password is a special case of substitution password.

Before learning affine cryptography, we first need to understand a few theorems

theorem

Unique Solution Theorem of Congruence Equation

Provided A the Z m , of any b∈Z m , congruence equation AX B (MOD m ) has a unique solution x ∈ Z m necessary and sufficient condition is the GCD ( A, m ) =. 1 *. *

Proof: Suppose gcd(a,m)=d>1, then the congruence equation ax=0(modm) has at least two solutions, x=0 and x=m/d. In this case, e(x)=(ax+b)modm is not an injective function, so it cannot be used as an effective encryption function.

With the above theorem, we can quickly judge whether a function is a valid encryption function. For example, gcd(26,2)=2 then 4x+7 is not a valid encryption function. Because for any x∈Z 26 , x and x+13 will be encrypted into the same ciphertext.

Next we look at spatial affine cipher keys, because 26 = 2 × 13, 26 and so all prime numbers is a = 1 3 5 7 9 11 15 17 19 21 23 25 the Z and b may be 26 in Therefore, the key space of affine cipher is 12×26=312. It can also be seen that affine cipher is very insecure.

Euler function and Euler's theorem

Let a 1*,* m 2. If gcd( a, m ) = 1, then a and m are relatively prime. The number of relatively prime elements of all domain m in Z m is represented by φ (m) (function φ is also called Euler function)

Insert picture description here

Use a popular formula to illustrate Euler's theorem:

φ(72) = φ(2 3 × 3 2 ) = 2 3-1 (2-1) × 3 2-1 (3-1) = 2 2 × 1 × 3 × 2 = 24

Multiplicative inverse

The Z provided a ∈ m , if there is a ' ∈Z m , such that AA ' . 1 (MOD m), called a reversible modulo m, a ' is a a (multiplicative) inverse, a ' may be referred to as a -1 mod m, when m is fixed, abbreviated as a -1

It can be seen from the previous conclusion that a has a multiplicative inverse on Z m , if and only if gcd(a,m)=1, and if its inverse exists, it must be unique.

In the case of Z 26 , the multiplicative inverse relative to 26 is shown in the following table:

Primary number 1 3 5 7 11 17 25
Reverse 1 9 21 15 19 23 25

Affine cipher

Let P=C=Z 26 and K={(a,b)∈Z 26 ×Z 26 : gcd(a,26)=1} for any k=(a,b)∈K, x,y belongs Z 26 , define e k (x)=(ax+b)mod26 and d k (y)=a -1 (yb)mod 26

Code

package com.slp.cryptography;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName AffineCipher
 * @Description 仿射密码
 * @Author sanglp
 * @Date 2020/11/30 14:43
 * @Version 1.0
 **/
public class AffineCipher {
    
    
    static Map<Integer,Integer> reverseMap = new HashMap<Integer,Integer>();
    static{
    
    
        reverseMap.put(1,1);
        reverseMap.put(3,9);
        reverseMap.put(9,3);
        reverseMap.put(5,21);
        reverseMap.put(21,5);
        reverseMap.put(7,15);
        reverseMap.put(15,7);
        reverseMap.put(11,19);
        reverseMap.put(19,11);
        reverseMap.put(17,23);
        reverseMap.put(23,17);
        reverseMap.put(25,25);
    }
    public static void main(String[] args) {
    
    
        encrypt("hot",7,3);
        decrypt("AXG",7,3);
    }

    /**
     * (ax+b)mod26 是加密函数
     * @param resource
     * @param a
     * @param b
     */
    public static void encrypt(String resource,int a,int b){
    
    
        if(!reverseMap.containsKey(a)|| b<0||b>26){
    
    
            throw new RuntimeException("参数有误,请重新输入");
        }
     char[] arr = resource.toUpperCase().toCharArray();
     StringBuilder result = new StringBuilder();
     for(int i=0;i<arr.length;i++){
    
    
       int temp =  (a*(arr[i]-'A')+b)%26<0?(a*(arr[i]-'A')+b)%26+26:(a*(arr[i]-'A')+b)%26;
         result.append((char)(temp+'A'));
     }
        System.out.println(result);
    }

    /**
     * 解密函数为a逆(y-b)mod26
     * @param resource
     * @param a
     * @param b
     */
    public static void decrypt(String resource,int a,int b){
    
    
        int  re =reverseMap.get(a);//求得逆 后续会整理求逆的方法
        char[] arr = resource.toUpperCase().toCharArray();
        StringBuilder result = new StringBuilder();
        for(int i=0;i<arr.length;i++){
    
    
            int temp = (re*(arr[i]-'A'-b))%26<0?(re*(arr[i]-'A'-b))%26+26:(re*(arr[i]-'A'-b))%26;
            result.append((char)(temp+'A'));
        }
        System.out.println(result);
    }
}

Guess you like

Origin blog.csdn.net/weixin_51656605/article/details/110388691