综合训练一:加密与解密
加密功能
- 输入一个大于 0 的整数作为原始密码(如:1983)。
- 按照以下规则加密:
- 拆分每一位数字;
- 每位数字加 5;
- 对结果取模 10 (即
%10),确保结果在 0~9 范围内; - 将处理后的数字序列反转,得到加密结果。
解密功能思路分析
- 将加密字符串拆分为单个数字;
- 将数字序列反转,还原加密前的顺序;
在加密过程中,每位原始数字
d(0~9)经过变换:
e = (d + 5) % 10,导致:
- 当
d ≤ 4时,e = d + 5(如 3 → 8)- 当
d ≥ 5时,e = d - 5(如 7 → 2)因此,从加密位
e反推原始d时:
- 若
e ≥ 5,说明未发生模运算,原始值为d = e - 5- 若
e ≤ 4,说明发生了"+5 后进位",原始值为d = e + 5为避免分支处理,代码还原思路如下:
- 对所有
e ∈ [0, 4]先加 10 → 使其变为 10~14,相当于"补回因模10丢失的10"- 所有位统一减 5 →
- 原
e = 2(≤4)→2 + 10 = 12→12 - 5 = 7- 原
e = 8(≥5)→ 保持 8 →8 - 5 = 3
完整代码:
java
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int password = sc.nextInt();
// 1. 计算输入整数的位数(通过不断除以10直到为0)
int temp1 = password;
int count = 0;
while(temp1 != 0){
temp1 /= 10;
count++;
}
// 2. 将每一位数字从高位到低位存入数组 arr 中
// (先取个位,但存到数组末尾,从而保证 arr[0] 是最高位)
int temp2 = password;
int index = (count-1);
int[] arr = new int[count];
while(temp2 != 0){
int ge = temp2 % 10; // 取当前最低位(个位)
arr[index] = ge; // 从数组末尾向前填充
temp2 /= 10; // 去掉已处理的个位
index--;
}
// 3. 对每一位进行加密:加5后对10取模,确保结果在0~9之间
for(int i = 0 ; i < arr.length ; i++){
arr[i] += 5;
arr[i] %= 10;
}
// 4. 将加密后的数组反转(模拟位置打乱)
int temp;
int l = 0, r = arr.length - 1;
String passwords = ""; // 用于拼接加密后的字符串
if(arr.length == 1){
// 只有一位数字,无需反转,直接拼接
passwords += arr[0];
}
else{
// 使用双指针法反转数组
while(l <= r){
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
l++;
r--;
}
// 将反转后的每一位拼接成字符串
for (int i = 0; i < arr.length; i++) {
passwords += arr[i];
}
}
// 4. 输出加密后的密码
System.out.println(passwords);
// 5. 解密:从加密字符串还原原始数字
// 5.1 将加密字符串 passwords 转换为整型数组 decArr
int[] decArr = new int[passwords.length()];
for(int i = 0 ; i < passwords.length() ; i++){
decArr[i] = passwords.charAt(i) - '0'; // 字符转数字
}
// 5.2 反转 decArr,还原加密前的数字顺序
int l2 = 0, r2 = decArr.length - 1;
int temp22;
if(decArr.length == 1){
// 只有一位,无需操作
}else{
// 双指针反转数组
while(l2 <= r2){
temp22 = decArr[l2];
decArr[l2] = decArr[r2];
decArr[r2] = temp22;
l2++;
r2--;
}
}
// 5.3 还原原始数字:先处理可能因减5变成负数的情况
// 若当前位是 0~4,说明原始加5后发生了进位(如 7+5=12→2),
// 因此需要先加10,再统一减5
for(int i = 0 ; i < decArr.length ; i++) {
if(decArr[i] >= 0 && decArr[i] <= 4) {
decArr[i] += 10;
}
}
// 统一减去5,得到原始每一位数字
for(int i = 0 ; i < decArr.length ; i++){
decArr[i] -= 5;
}
// 5.4 将解密后的数字拼接成字符串
String original = "";
for(int i = 0 ; i < decArr.length ; i++){
original += decArr[i];
}
// 5.5 输出解密结果(应与用户输入的 password 一致,除非输入为0)
System.out.println(original);
}
}

综合训练二:随机验证码的生成
- 定义一个方法,用于随机生成一个5位验证码。
- 验证码格式要求:
- 长度为5;
- 前四位为大写字母或小写字母(任意一种均可);
- 最后一位为数字。
完整代码:
java
import java.util.Random;
public class Test1 {
public static void main(String[] args) {
// 创建一个长度为52的字符数组,用于存储26个小写字母和26个大写字母
char[] chs = new char[52];
// 1.填充字符数组:前26个位置存小写字母 'a' 到 'z',后26个位置存大写字母 'A' 到 'Z'
for (int i = 0; i < chs.length; i++) {
if (i <= 25) {
// i 从 0 到 25:对应 'a' + 0 到 'a' + 25 → 'a' 到 'z'
chs[i] = (char) ('a' + i);
} else {
// i 从 26 到 51:对应 'A' + (i - 26) → 'A' 到 'Z'
chs[i] = (char) ('A' + i - 26);
}
}
// 2.创建 Random 对象,用于生成随机索引
Random r = new Random();
// 初始化验证码字符串
String code = "";
// 用于存储随机生成的数组下标
int randomIndex;
// 3.循环4次,每次从字符数组中随机选取一个字母(大小写混合),拼接到验证码中
for (int i = 0; i < 4; i++) {
// 生成 [0, 52) 范围内的随机整数,作为 chs 数组的下标
randomIndex = r.nextInt(chs.length);
// 将随机选中的字符追加到 code 字符串末尾
code+= chs[randomIndex];
}
// 生成一个 [0, 10) 范围内的随机数字(0 到 9),并拼接到验证码末尾
int randomNumber = r.nextInt(10);
code += randomNumber;
// 最终生成5位密码(4个随机字母 + 1个随机数字)
System.out.println(code);
}
}
