public class MyBubbleBubble {
static final String vowels = "aeiouy";//元音表
static final String consonants = "bcdfghklmnprstvzx";//常量表
/**
* 对原文进行bubble bubble编码
* @param str 原文字符串
* @return 编码字符串
*/
static String encrypt(String str){
int k = str.length();//明文长度
byte[] D = str.getBytes();//字节数据
byte[] C = new byte[k/2+1];//校验和
int[][] T = new int[k/2][5];//5元组
int[] P = new int[3];//三元组
for(int i=0; i<k/2+1; i++){
C[i] = i==0 ? 1:(byte) ((C[i-1]*5 + D[(i+1)*2-3-1]*7 + D[(i+1)*2 - 2 -1]) % 36);
}
for(int i=0; i<k/2; ++i){//每两个数据构建一个五元组
int a = (((D[i*2] >> 6) & 3) + C[i]) % 6;
int b = (D[i*2] >> 2) & 15;
int c = (D[i*2] & 3) + (C[i]/6) % 6;
if(2*i+1 >= k)
break;
int d = (D[i*2+1] >> 4) & 15;
int e = (D[i*2+1]) & 15;
T[i][0] = a;
T[i][1] = b;
T[i][2] = c;
T[i][3] = d;
T[i][4] = e;
}
//三元组
P[0] = k%2 == 0 ? C[k/2] % 6 : (((D[k-1] >> 6) & 3) + C[k/2]) % 6;
P[1] = k%2 == 0 ? 16 : (D[k-1] >> 2) & 15;
P[2] = k%2 == 0 ? C[k/2] / 6 : ((D[k-1] & 3) + C[k/2] / 6) % 6;
String out = "x";
for(int i=0; i<T.length; i++){
out += vowels.charAt(T[i][0]) + ""+ consonants.charAt(T[i][1]) + vowels.charAt(T[i][2]) + consonants.charAt(T[i][3]) + "-" + consonants.charAt(T[i][4]);
}
out +=vowels.charAt(P[0]);
out +=consonants.charAt(P[1]);
out +=vowels.charAt(P[2]);
out += 'x';
System.out.println(out);
return out;
}
/**
* 对bubble bubble 编码的字符串进行解码
* @param str 编码字符串
* @return 原始数据
*/
public static String decrypt(String str){
int c = 1;
String output = "";
str = str.substring(1, str.length()-1);//取出x
HashMap<Integer, String> map = new HashMap<>();
for(int i=0, j=0; i<str.length(); i+=6, j++){//因为每6个字符中去除-就是一个五元组
map.put(j, str.substring(i, i+6 > str.length() ? str.length():i+6));
}
int lastTupple = map.size()-1;
for(Map.Entry<Integer, String> each: map.entrySet()){
int index = each.getKey();
String val = each.getValue();
ArrayList<String> tup = new ArrayList();
tup.add(""+vowels.indexOf(val.charAt(0)));
tup.add(""+consonants.indexOf(val.charAt(1)));
tup.add(""+vowels.indexOf(val.charAt(2)));
try{
tup.add(""+consonants.indexOf(val.charAt(3)));
tup.add("-");
tup.add(""+consonants.indexOf(val.charAt(5)));
}catch (Exception e){
}
int high = (Integer.parseInt(tup.get(0)) - (c % 6) + 6) % 6;
int mid = Integer.parseInt(tup.get(1));
int low = (Integer.parseInt(tup.get(2)) - (c/6%6) + 6) % 6;
byte b = (byte) (high << 6 | mid << 2 | low);
if(lastTupple == index){
if(!tup.get(1).equals("16")){
output += (char)b;
}
}else{
output += (char)b;
byte b1 = (byte) (Integer.parseInt(tup.get(3)) << 4 | Integer.parseInt(tup.get(5)));
output += (char)b1;
c = (c*5 + b*7 + b1) % 36;
}
}
System.out.println(output);
return output;
}
public static void main(String[] args) {
decrypt(encrypt("Pineapple"));
}
}