bubble bubble encoding编码原理

西门梓
2023-12-01

编码步骤:

1.设置一个D[k]数组D[0],...,D[k-1]用于存放原文字节数据,K为明文长度
 
2.设置一个C[k/2+1]数组,C[0],...,C[k/2]用于存放校验和
    C[0] = 1
    C[i] = (C[i-1] * 5 + (D[i * 2 -2] * 7 + D[i * 2 - 1])) % 36,i是从1到k/2的数组下标
 
3.设置一个二维数组T[k/2][5],T[0],...T[k/2-1]用于存放元组<a, b, c, d, e>
    T[i] = <a, b, c, d, e>
    a = (((D[i*2] >> 6) & 3) + C[i]) % 6;
    b = (D[i*2] >> 2) & 15;
    c = (D[i*2] & 3) + (C[i]/6)  % 6;
    d = (D[i*2+1] >> 4) & 15;
    e = (D[i*2+1]) & 15;
4.设置一个数组P[3],用于存放三元组<a, b, c>
    p = <a, b, c>
    如果k是偶数:
        a = C[k/2] % 6
        b = 16
        c = C[k/2] / 6
    如果k是奇数:
        a = (((D[k-1] >> 6) & 3) + C[k/2]) % 6;
        b = (D[k-1] >> 2) & 15;
        c = ((D[k-1] & 3) + C[k/2] / 6) % 6; 
5.元音表(vowel table,用V表示)
    0 - a
    1 - e
    2 - i
    3 - o
    4 - u
    5 - y
6.常量表(consonant, 用C表示)
    0 - b
    1 - c
    2 - d
    3 - f
    4 - g
    5 - h
    6 - k
    7 - l
    8 - m
    9 - n
    10 - p
    11 - r
    12 - s
    13 - t
    14 - v
    15 - z
    16 - x
7.依次对T[i] = <a, b, c, d, e>的元组进行编码,规则如下
    V[a] C[b] V[c] C[d] '-' C[e]
8.在对编码后的元组后再加上对P编码的元组,规则如下
    V[a] C[b] V[c]
9.最后再编码后的字符串的一头一尾加上x,结果如下
    XE(T[1]) E(T[2]) ... E(T[|K/2|]) E(P)X
 

java实现编码和解码

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"));
    }
}

 

 类似资料: