java: 重构编码密码
java: refactor encode cipher
所以我实现了一个带有换位密码的编码方法,我提供了一个密钥和一条文本消息。
可视化
关键:“伙计”
消息:“hellobro”
我根据关键字母的字母顺序分配数字(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 循环?
我试过省略索引,但还没有让它工作..
任何帮助将不胜感激!
一般备注
重构和代码风格在某种程度上是个人化的。所以我想并不是所有人都同意我的看法。
一些好的做法是确保您的代码简洁,但 class、方法和变量名称也应反映它们 and/or 的作用。您选择的名称应该有助于阅读代码。如果方法太长,请创建一个新方法以提高可读性。
在您当前的代码中,您可以用另一种方法替换 csize 的计算。您还可以选择更具可读性的变量,例如更改变量 str。
有关于正确 Java 代码的完整书籍。 Martin Fowler 写了一个比较流行的。所以,这些小言论根本没有涵盖重构主题。
你的方法的目标
你解释了你想做什么。但是,您的密钥(DUDE)的用途似乎不清楚。它实际上没有被使用。如果您使用其他键测试您的代码,它具有完全相同的顺序。所以,那里似乎有些不对劲。
省略一个循环的代码
对于所有有丰富经验的人来说:这绝对可以进一步改进 and/or 可以采用不同的结构。此代码使用与原始代码相同的方法参数,并产生与原始代码相同的测试结果 post。我没有尝试解释缺少使用密钥(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]
所以我实现了一个带有换位密码的编码方法,我提供了一个密钥和一条文本消息。
可视化
关键:“伙计”
消息:“hellobro”
我根据关键字母的字母顺序分配数字(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 循环?
我试过省略索引,但还没有让它工作..
任何帮助将不胜感激!
一般备注
重构和代码风格在某种程度上是个人化的。所以我想并不是所有人都同意我的看法。 一些好的做法是确保您的代码简洁,但 class、方法和变量名称也应反映它们 and/or 的作用。您选择的名称应该有助于阅读代码。如果方法太长,请创建一个新方法以提高可读性。 在您当前的代码中,您可以用另一种方法替换 csize 的计算。您还可以选择更具可读性的变量,例如更改变量 str。 有关于正确 Java 代码的完整书籍。 Martin Fowler 写了一个比较流行的。所以,这些小言论根本没有涵盖重构主题。
你的方法的目标
你解释了你想做什么。但是,您的密钥(DUDE)的用途似乎不清楚。它实际上没有被使用。如果您使用其他键测试您的代码,它具有完全相同的顺序。所以,那里似乎有些不对劲。
省略一个循环的代码
对于所有有丰富经验的人来说:这绝对可以进一步改进 and/or 可以采用不同的结构。此代码使用与原始代码相同的方法参数,并产生与原始代码相同的测试结果 post。我没有尝试解释缺少使用密钥(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]