[Práctica y principios de criptografía] (3) Implementación de cifrados afines en código Java

Cifrado afín

Vuelva a imprimir la fuente

La contraseña afín es un caso especial de contraseña de sustitución.

Antes de aprender la criptografía afín, primero debemos comprender algunos teoremas

teorema

Teorema de solución único de la ecuación de congruencia

Siempre que A la Z m , de cualquier b∈Z m , la ecuación de congruencia AX B (MOD m ) tenga una solución única x ∈ Z m necesaria y la condición suficiente es la MCD ( A, m ) =. 1 *. *

Prueba: Suponga que mcd (a, m) = d> 1, entonces la ecuación de congruencia ax = 0 (modm) tiene al menos dos soluciones, x = 0 y x = m / d. En este caso, e (x) = (ax + b) modm no es una función inyectiva, por lo que no se puede utilizar como una función de cifrado eficaz.

Con el teorema anterior, podemos juzgar rápidamente si una función es una función de cifrado válida. Por ejemplo, mcd (26,2) = 2 entonces 4x + 7 no es una función de cifrado válida. Porque para cualquier x∈Z 26 , x y x + 13 se cifrarán en el mismo texto cifrado.

A continuación, observamos las claves de cifrado afines espaciales, porque 26 = 2 × 13, 26 y, por lo tanto, todos los números primos son a = 1 3 5 7 9 11 15 17 19 21 23 25 la Z yb pueden ser 26 en Por lo tanto, el espacio clave de cifrado afín es 12 × 26 = 312. También se puede ver que el cifrado afín es muy inseguro.

Función de Euler y teorema de Euler

Sea a 1 *, * m 2. Si mcd ( a, m ) = 1, entonces a y m son primos relativos. El número de elementos primos relativos de todo el dominio m en Z m está representado por φ (m) (la función φ también se llama función de Euler)

Inserte la descripción de la imagen aquí

Utilice una fórmula popular para ilustrar el teorema de Euler:

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

Multiplicación inversa

La Z proporcionó a ∈ m , si hay un ' ∈Z m , tal que AA ' . 1 (MOD m), llamado módulo reversible m, a ' es un inverso a (multiplicativo), a ' puede referirse a como -1 mod m, cuando m es fijo, abreviado como -1

De la conclusión anterior se puede ver que a tiene un inverso multiplicativo en Z m , si y solo si mcd (a, m) = 1, y si su inverso existe, debe ser único.

En el caso de Z 26 , el inverso multiplicativo relativo a 26 se muestra en la siguiente tabla:

Numero primario 1 3 5 7 11 17 25
Contrarrestar 1 9 21 15 19 23 25

Cifrado afín

Sea P = C = Z 26 y K = {(a, b) ∈Z 26 × Z 26 : mcd (a, 26) = 1} para cualquier k = (a, b) ∈K, x, y pertenece a Z 26 , define e k (x) = (ax + b) mod26 yd k (y) = a -1 (yb) mod 26

Código

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);
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_51656605/article/details/110388691
Recomendado
Clasificación