我尝试使用带有键位置整数的ascii字符加密字符串。我有两种方法,一种用于加密,一种用于解密。
问题是,当字符值高于126时,我尝试对其进行修改126然后再添加32,但是我得到的数字远远超出这些限制。
public static String encrypt(String s, int k) {
char[] arr = s.toCharArray();
int ascii;
for(int i = 0; i < arr.length; i++) {
ascii = (int) arr[i];
ascii = ascii + k;
// System.out.println(ascii);
if (ascii > 126) {
ascii = 32 + (126 % ascii);
// System.out.print("Changed: " + ascii);
}
arr[i] = (char) ascii;
}
return String.valueOf(arr);
}
两条注释掉的线路用于测试,并且更改的值是疯狂的高,而不是从127%126 = 1 + 32到总共33(预期值),我得到15870。
答案 0 :(得分:0)
你的modulo语句是向后写的一个开始。尝试:
ascii = 32 + (ascii % 126);
答案 1 :(得分:0)
首先,正如mypetlion所提到的,当a除以b时,模运算a%b等于余数。例如。 11%4 = 3,8%15 = 8.准确地说,它是满足b * n + k = a,b *(n + 1)>的值k。 a,k&lt; b其中n是整数。使用离散数学有更合适的描述,我忽略了否定的论点,但它们并不重要。所以在你的情况下你应该做ascii%128。
为什么模数应该是128而不是126,7位ascii代码从0-127,总共128个值。另外我对+32的含义感到有点困惑,因为你已经做了+ k。
此外,您可以完全省略if块,因为c%128 = c表示[0,128]范围内的任何c。
所以我会写下面的代码:
public static String encrypt(String s, int k) {
char[] arr = s.toCharArray();
for(int i = 0; i < arr.length; i++){
arr[i] = (char) ((arr[i] + k) % 128);
}
return String.valueOf(arr);
}
public static String decrypt(String s, int k) {
char[] arr = s.toCharArray();
for(int i = 0; i < arr.length; i++){
arr[i] = (char) ((arr[i] + 128 - k % 128) % 128);
// + 128 - k % 128 because I don't want do deal with negative numbers.
}
return String.valueOf(arr);
}
我相信我的代码会起作用(对于k的所有正值),但我无法解释为什么你的代码产生了一些疯狂的高ascii值。当我在我的IDE上运行你的代码时,它没有那样做,也不能从你的代码中看到它的原因。
最后,这个密码方法会加密和解密,但请注意,ascii确实包含许多不易打印的控制字符。因此,如果您希望将密码词汇限制为仅字母和标点符号,则需要进行一些字符映射以限制要加密和加密的字符。这将会复杂得多,更不用说你必须考虑像Windows v.LF中的CR + LF这样的问题。以下是仅加密和解密字母的简单示例。
public static int asciiToCustom(char ascii) {
// Maps 65-90 & 97-122 to 0-51.
int customCode;
if(ascii >= 65 && ascii <= 90){
customCode = ascii - 65;
}
else if(ascii >= 97 && ascii <= 122){
customCode = ascii - 71;
}
else{
throw new RuntimeException("not a letter!");
}
return customCode;
}
public static char customToAscii(int custom) {
// Maps 0-51 to 65-90 & 97-122.
int ascii;
if(custom >= 0 && custom <= 25){
ascii = custom + 65;
}
else if(custom >= 26 && custom <= 51){
ascii = custom + 71;
}
else{
throw new RuntimeException("not a valid custom code!");
}
return (char) ascii;
}
public static String encrypt(String s, int k) {
char[] arr = s.toCharArray();
for(int i = 0; i < arr.length; i++){
if(Character.isLetter(arr[i])){
arr[i] = customToAscii((asciiToCustom(arr[i]) + k) % 52);
}
}
return String.valueOf(arr);
}
public static String decrypt(String s, int k) {
char[] arr = s.toCharArray();
for(int i = 0; i < arr.length; i++){
if(Character.isLetter(arr[i])){
arr[i] = customToAscii((asciiToCustom(arr[i]) + 52 - k % 52) % 52);
// + 52 - k % 52 because I don't want do deal with negative numbers.
}
}
return String.valueOf(arr);
}