java:重构编码密码



所以我用换位密码实现了一个编码方法,并提供了一个密钥和一条文本消息。

  • 可视化
    键:"花花公子
    消息:"你好兄弟">
    我根据关键字母的字母顺序分配数字(int数组(。

    D U D E
    0 1 3 2
    h E l l
    o b r o

算术排序
D D E U
0 1 2 3
h l l E
o r o b

那么";读取";按列:加密消息:";holrloeb";

  • 实现
import java.util.*;
public class test1 {
public static String encode(String textraw, String key){
int csize = 0, index = 0;
int[] numbers = {0,3,1,2};
int mod = textraw.length() % key.length();
int div = textraw.length() / key.length();
// calculate size of column
if (mod == 0) {
csize = div;
} else {
csize = div + 1;
}
int[] snumbers = numbers.clone();
Arrays.sort(snumbers);
// Sort columns
StringBuilder str = new StringBuilder(textraw.length());
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers.length; j++) {
if (snumbers[i] == numbers[j]){
index = snumbers[j];
break;
}
}
// create string column by column
for (int j = 0; j < csize; j++) {
if (index < textraw.length()) {
str.append(textraw.charAt(index));
index += numbers.length;
}
}
}
return str.toString();
}
public static void main(String[] args){
String s = "hellobro";
String keyk = "DUDE";
System.out.println("encrypted -> "+encode(s,keyk));
}
}

我的问题是如何重构encode方法,至少去掉第二个嵌套的for循环?

我试过省略索引,但还没起作用
如有任何帮助,我们将不胜感激!

一般备注

重构和代码风格在某种程度上是个人的。所以我想并不是所有人都同意我的观点。一些好的做法是确保你的代码简洁,但类、方法和变量名也应该反映它们是什么和/或做什么。你选择的名称应该有助于阅读代码。如果一个方法太长,请创建一个新方法以提高可读性。在您当前的代码中,您可以用另一种方法替换csize的计算。您还可以选择可读性更强的变量,例如更改变量str。关于正确的Java代码,有完整的书籍。马丁·福勒写了一本比较受欢迎的书。因此,这些小注释根本不涉及重构主题。

方法的目标

你解释了你想做什么。但是,你的钥匙(DUDE(的用途似乎不清楚。它实际上没有被使用。如果用其他键测试代码,则其顺序完全相同。所以,似乎有什么不对劲。

省略一个循环的代码

对于所有有丰富经验的人来说:这肯定可以得到更多的改进和/或以不同的方式构建。此代码使用与原始代码相同的方法参数,并生成与原始帖子相同的测试结果。我没有试图解释没有使用密钥(DUDE(。

import java.util.Arrays;
class Scratch {
public static void main(String[] args) {
Cipher c = new Cipher();
c.tests();
}
}
class Cipher {
public String encode(String textraw, String key) {
StringBuilder resultString = new StringBuilder();
Integer[] numbers = {0, 3, 1, 2};
//split your textraw into substrings of 4
String[] splitString = textraw.split("(?<=\G.{"+numbers.length+"})");
for(int i = 0; i < numbers.length; i++){
//get the index of the number I in your numbers array
int foundIndex = Arrays.asList(numbers).indexOf(i);
//should give 0,2,3,1 in the loop
for(int k = 0; k < splitString.length; k++){
//get the foundIndex from all substrings in splitStrings and add to the stringbuilder
//you are looking for splitStrings[k].charAt(foundIndex)
if(foundIndex < splitString[k].length()){
//This avoids errors when the last string is shorter than the maximum chars
resultString.append(splitString[k].charAt(foundIndex));
}
}
}
return resultString.toString();
}

public void tests() {
String input;
String key;
input = "hellobro";
key = "DUDE";
System.out.println("Encoding " + input + " with key " + key + " gives result: " + encode(input, key));
input = "dudedude";
key = "DUDE";
System.out.println("Encoding " + input + " with key " + key + " gives result: " + encode(input, key));
input = "abcdabcdabc";
key = "ABCD";
System.out.println("Encoding " + input + " with key " + key + " gives result: " + encode(input, key));
}
}

使用字符串键(DUDE(

您可以添加一个从字符串中获取排序键的方法。此方法生成排序的ArrayList。所以你必须把数字设为ArrayList<Integer> numbers = getKeyArray(key);您必须将numbers.length更改为numbers.size(),然后foundIndex到int foundIndex = numbers.indexOf(i);

带有测试的getKeyArray方法

private ArrayList<Integer> getKeyArray(String key) {
String alfabet = "abcdefghijklmnopqrstuvwxyz";
ArrayList<Integer> resultArrayList = new ArrayList<>();
HashMap<Integer, Integer> charRank = new HashMap<>();
for (int k = 0; k < key.length(); k++) {
int alfabetIndex = alfabet.indexOf(Character.toLowerCase(key.charAt(k)));
charRank.put(k, alfabetIndex);
}
charRank.entrySet()
.stream()
.sorted(Map.Entry.<Integer, Integer>comparingByValue()).forEach(e -> resultArrayList.add(e.getKey()));
return resultArrayList;
}
public void testGetKeyArray() {
String testInput;
testInput = "ABDCEFG";
System.out.println("Test getKeyArray with " + testInput);
getKeyArray(testInput).forEach(System.out::println);
testInput = "DUDE";
System.out.println("Test getKeyArray with " + testInput);
getKeyArray(testInput).forEach(System.out::println);
}

输出示例getKeyArray

"GFEABCD" Result: [3, 4, 5, 6, 2, 1, 0] 
"ABDCEFG" Result: [0, 1, 3, 2, 4, 5, 6]

最新更新