![cover](https://i-blog.csdnimg.cn/blog_migrate/cover/db3787141d668b1b21ce6510b847fa3b.png)
华为OD机试之敏感字段加密(java源码)
给定一个由多个命令字组成的命令字符串:1、字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号2、命令字之间以一个或多个下划线 _ 进行分割;3、可以通过两个双引号”来标识包含下划线 的命令字或空命令字(仅包含两个双引号的命令字),双引号不会在命令字内部出现请对指定索引的敏感字段进行加密,替换为****** (6个*) ,并删除命令字前后多余的下划线如果无法找到指定索引的命令
敏感字段加密
给定一个由多个命令字组成的命令字符串:
1、字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号
2、命令字之间以一个或多个下划线 _ 进行分割;
3、可以通过两个双引号”来标识包含下划线 的命令字或空命令字(仅包含两个双引号的命令字),双引号不会在命令字内部出现
请对指定索引的敏感字段进行加密,替换为****** (6个*) ,并删除命令字前后多余的下划线如果无法找到指定索引的命令字,输出字符串ERROR。
输入描述
输入为两行,第一行为命令字索引K (从0开始) ,第二行为命令字符串S.
输出描述
输出处理后的命令字符串,如果无法找到指定索引的命令字,输出字符串ERROR
输入1 | 输入2 | 输出 | 说明 |
---|---|---|---|
1 | password__a12345678_timeout_100 | password_******_timeout_100 | 加密第二个命令字 |
2 | aaa_password_“a12_45678”timeout__100_“”_ | aaa_password_******_ timeout__“” | 加密第三个命令字 |
源码和解析
解析:
1.将输入的命令字串转换成单字符数组 char[]
2.遍历单字符数组,并判断单个字符的含义
2.1 遍历字符数组,遇到指令截止符,则代表一个命令字结束,截止符有以下几种情况
2.1.1 第二次双引号出现
2.1.2 下划线(需要判断是否前面有引号,若有,则代表不是截止符。空下划线过滤掉)
2.1.3 字符数组遍历结束时 即最后一个字符
2.2 不断产生命令字后加入List之中
2.3 判断输入的索引是否越界
2.3.1 若越界 则输出ERROR
2.3.2 若未越界 将索引对应位置的命令字替换为*****
2.4 遍历List 产生最后的加密指令
示例代码:
import java.util.*;
import java.util.Scanner;
public class T1 {
static Scanner scanner=new Scanner(System.in);
public static void main(String[] args) {
System.out.println("请输入索引:");
int index=Integer.parseInt(scanner.nextLine());
System.out.println("请输入命令串:");
String input=scanner.nextLine();
char[] chArr=input.toCharArray();
String cmd="";
List<String> cmdList=new ArrayList<>();
for(int i=0;i<chArr.length;i++){
char item=chArr[i];
if(item=='"'&&cmd.contains(item+"")){
//如果是双引号 且该命令字内有 那么就是结束的双引号
cmd+="\"";
cmdList.add(cmd);
cmd="";
}else if(item=='_'&&!cmd.contains("\"")){
//item=='_' 下划线 表示指令结束
//!cmd.contains("\"") 该命令内前面不包含" 若包含 则是引号内的 为同一个命令字
//cmd.equals("") 该命令字内是空的 那么就是空下划线 无意义 过滤掉
if(!cmd.equals("")){
cmdList.add(cmd);
cmd="";
}
}
else if(i==chArr.length-1){
//如果是最后一位 则直接结束最后一个命令字
cmd+=item;
cmdList.add(cmd);
cmd="";
}
else{
//其他 情况 则是命令字
cmd+=item;
}
}
//password__a12345678_timeout_100
//aaa_password_"a12_45678"_timeout__100_""_
if(index>cmdList.size()-1||index<0){
System.out.println("ERROR");
}else{
cmdList.set(index, "******");
String result="";
for(String item:cmdList){
result+="_"+item;
}
result=result.replaceFirst("_", "");
System.out.println(result);
}
}
}
若需要提高效率,则可以考虑使用StringBuilder或StringBuffer来完成。而不是直接使用String字符串进行拼接。
String 是 Java 中基础且重要的类,被声明为 final class,是不可变字符串。因为它的不可变性,所以拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。
StringBuffer 就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类。它提供了 append 和 add 方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列。
在很多情况下我们的字符串拼接操作不需要线程安全,所以 StringBuilder 登场了。StringBuilder 是 JDK1.5 发布的,它和 StringBuffer 本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。
线程安全:
StringBuffer:线程安全
StringBuilder:线程不安全
速度:
一般情况下,速度从快到慢为 StringBuilder > StringBuffer > String,当然这是相对的,不是绝对的。
使用环境:
操作少量的数据使用 String。
单线程操作大量数据使用 StringBuilder。
多线程操作大量数据使用 StringBuffer。
更多推荐
所有评论(0)