1. 凯撒加密算法 (对称算法)

打印 上一主题 下一主题

主题 878|帖子 878|积分 2634

1. 凯撒加密算法

1.1 算法逻辑

根据一个固定偏移值(offset), 将字母向一个方向偏移, 进行加密.
1.2 初步思路


  • 获取明文(plaintext)
  • 获取明文字符串的单独字符
  • 进行字符值偏移
  • 当偏移超出字母范围时, 回到第一个字母处继续偏移.
  • 得到密文(ciphertext)
1.3 初步编程
  1. /*
  2. 凯撒密码:
  3. 偏移量
  4. A(65)~Z(90)
  5. a(97)~z(122)
  6. 方法1: 但偏移量超过范围时, 返回到最初循环
  7. 方法二:进行数组偏移(加密)
  8. 方法三:进行数组回位(解密)
  9. */
  10. public class Task01_Caesar {
  11.     public static void main(String[] args) {
  12.         // 输入明文
  13.         String plaintext = "I told it was a lie. ";
  14.         // 明文加密
  15.         String password = leadingPlaintext(plaintext, 10);
  16.         System.out.println(password);
  17.         // 密文解密
  18.         String plaintext1 = leadingPassword(password, 10);
  19.         System.out.println(plaintext1);
  20.     }
  21.     // 凯撒密码加密
  22.     public static String leadingPlaintext(String plaintext, int leadingNum) {
  23.         String password = "";
  24.         // 将明文转化成字符数组
  25.         char[] charPassword = plaintext.toCharArray();
  26.         // 进行加密操作
  27.         int[] intPassword = new int[charPassword.length];
  28.         for (int i = 0; i < charPassword.length; i++) {
  29.             // 将字符数组转化成字符码数组
  30.             intPassword[i] = (int)charPassword[i];
  31.             // 字符码数组偏移&范围限定
  32.             intPassword[i] = limitLetter(intPassword[i], intPassword[i]+leadingNum);
  33.             // 偏移字符码数组重新输出为字符数组
  34.             charPassword[i] = (char)intPassword[i];
  35.             // 将字符数组转化成字符串
  36.             password = String.valueOf(charPassword);
  37.         }
  38.         return password;
  39.     }
  40.     // 凯撒密码解密
  41.     public static String leadingPassword(String password, int leadingNum) {
  42.         String plaintext = "";
  43.         // 将密码转化成字符数组
  44.         char[] charPassword = password.toCharArray();
  45.         // 进行解密操作
  46.         int[] intPassword = new int[charPassword.length];
  47.         for (int i = 0; i < charPassword.length; i++) {
  48.             // 将字符数组转化成字符码数组
  49.             intPassword[i] = (int)charPassword[i];
  50.             // 字符码数组偏移&范围限定
  51.             intPassword[i] = limitLetter(intPassword[i], intPassword[i]-leadingNum);
  52.             // 偏移字符码数组重新输出为字符数组
  53.             charPassword[i] = (char)intPassword[i];
  54.             // 将字符数组转化成字符串
  55.             plaintext = String.valueOf(charPassword);
  56.         }
  57.         return plaintext;
  58.     }
  59.     // 进行范围限定
  60.     public static int limitArea(int num, int min, int max) {
  61.         int area = 26;  // 限定范围区间
  62.         while (num < min || num > max) {
  63.             if (num < min) {
  64.                 num += area;
  65.             } else if (num > max) {
  66.                 num -= area;
  67.             }
  68.         }
  69.         return num;
  70.     }
  71.     // 进行字母范围限定
  72.     public static int limitLetter(int originNum, int leadingNum) {
  73.         if (originNum >=65 && originNum <= 90) {
  74.             leadingNum = limitArea(leadingNum, 65, 90);
  75.         } else if (originNum >= 97 && originNum <= 122) {
  76.             leadingNum = limitArea(leadingNum, 97, 122);
  77.         }
  78.         return leadingNum;
  79.     }
  80. }
复制代码
1.5 思路重置


  • 不需要将字符串转化为字符数组, 可以通过String.charAt()方法在for循环里直接获取单独的字符. 不需要使用String.toCharArray()方法将字符串转化为字符数组.
  • 因为字符char本质其实是数字, 所以可以直接使用char进行逻辑判断, 不需要将其转换为数字码点再判断.
  • 当需要框定一个数的范围, 进行A-B循环时, 可以通过取余操作进行限定.
    b = (b % 26)+1 (限定范围1~26的数字)
1.6 A-B循环

[code]/** description: 1~26循环数输出 */public class Task03_ABLoop {    public static void main(String[] args) {        for (int i = 0; i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

不到断气不罢休

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表