【密码学原理与实践】(三)仿射密码 符java代码实现

仿射密码(Affine Cipher)

转载请著明出处

仿射密码是代换密码的一种特殊情况。

在学习仿射密码之前我们首先需要了解几个定理

定理

同余方程唯一解定理

a Zm,对任意的b∈Zm,同余方程ax b (mod m)有唯一解x∈Zm的充分必要条件是gcd(a, m) = 1*.*

证明:假设gcd(a,m)=d>1,则同余方程ax=0(modm)至少有两个解,分别是x=0和x=m/d。这种情况下e(x)=(ax+b)modm不是一个单射函数,因此不能用了作为一个有效的加密函数。

有了如上的定理我们就很快能判断一个函数是否是有效的加密函数,比如gcd(26,2)=2那么4x+7不是一个有效的加密函数。因为对任意的x∈Z26,x和x+13将被加密成相同的密文。

接下来我们看一下仿射密码的秘钥空间,因为26=2×13,所以所有与26互素的数为a= 1 3 5 7 9 11 15 17 19 21 23 25而b可能是Z26中的任何数,因此仿射密码的秘钥空间为12×26=312.由此也可以看出仿射密码是很不安全的。

欧拉函数和欧拉定理

a 1*,* m 2. 如果 gcd(a, m) = 1, 则称a与m互素。Zm中所有域m互素元素个数用φ(m)来表示(函数φ也称为欧拉函数)

在这里插入图片描述

以一个通俗的式子来说明欧拉定理:

φ(72)=φ(23×32)=23-1(2-1)×32-1(3-1)=22×1×3×2=24

乘法逆

设a∈ Zm,若存在a∈Zm,使得aa1(mod m),则称a模m可逆,a为a的(乘法)逆元,a可记为a-1 mod m,在m固定的情形下,简记为a-1

由之前的结论可知,a在Zm上存在乘法逆,当且仅当gcd(a,m)=1,并且其逆如果存在,则必唯一。

在Z26的情形下,与26互素的乘法逆如下表所示:

原数 1 3 5 7 11 17 25
1 9 21 15 19 23 25

仿射密码

令P=C=Z26,且K={(a,b)∈Z26×Z26 :gcd(a,26)=1}对任意的k=(a,b)∈K, x,y属于Z26,定义ek(x)=(ax+b)mod26和dk(y)=a-1(y-b)mod 26

代码实现
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>(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
密码学中的仿射变换是一种简单的加密技术,它将明文中的每个字母映射到另一个字母,映射关系由一个线性函数定义。具体实现过程如下: 1. 定义一个包含所有可用字母的字符集,例如A-Z和a-z的字母和一些标点号。 2. 定义一个线性函数f(x) = ax + b,其中a和b是密钥参数,x是字符集中的一个字母。 3. 对于每个明文中的字母x,计算仿射变换后的密文字母y = f(x),并将其存储在结果字符串中。 以下是Java实现代码: ```java public class AffineCipher { private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.?! "; public static String encrypt(String plaintext, int a, int b) { StringBuilder ciphertext = new StringBuilder(); for (int i = 0; i < plaintext.length(); i++) { char c = plaintext.charAt(i); int index = CHARACTERS.indexOf(c); if (index != -1) { int y = (a * index + b) % CHARACTERS.length(); ciphertext.append(CHARACTERS.charAt(y)); } else { ciphertext.append(c); } } return ciphertext.toString(); } public static String decrypt(String ciphertext, int a, int b) { StringBuilder plaintext = new StringBuilder(); int a_inverse = modInverse(a, CHARACTERS.length()); for (int i = 0; i < ciphertext.length(); i++) { char c = ciphertext.charAt(i); int index = CHARACTERS.indexOf(c); if (index != -1) { int x = (a_inverse * (index - b + CHARACTERS.length())) % CHARACTERS.length(); plaintext.append(CHARACTERS.charAt(x)); } else { plaintext.append(c); } } return plaintext.toString(); } private static int modInverse(int a, int m) { a %= m; for (int x = 1; x < m; x++) { if ((a * x) % m == 1) { return x; } } return 1; } public static void main(String[] args) { String plaintext = "Hello, world!"; int a = 5; int b = 8; String ciphertext = encrypt(plaintext, a, b); System.out.println("Ciphertext: " + ciphertext); String decrypted = decrypt(ciphertext, a, b); System.out.println("Decrypted text: " + decrypted); } } ``` 在这个实现中,我们使用了一个包含所有可用字母的字符集,并定义了一个encrypt和decrypt方法来进行加密和解密。我们还实现了一个modInverse方法来计算模反元素,以便在解密时使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值