读书人

基于UTF-8编码的等长添解扰算法(java)

发布时间: 2012-08-22 09:50:35 作者: rapoo

基于UTF-8编码的等长加解扰算法(java)
使用“三区映射”方法针对中英文数字混杂的字符串进行等长的加解扰,适用于安全性较低的情景,方便查询出库再加扰入库,字段长度不变。(gbk编码的环境同样可以使用三区映射方法进行加解扰设计)



/** * 等长加扰解扰 * @author Jerry */public final class UTFBasedEqualLengthCipher{    private static final char[] EN_RED =    {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',     'o', 'p', 'q', 'r', 's', 't', 'u'};    private static final char[] EN_YELLOW =    {'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '@', '5', '6', '7',     '8', '9', 'Z', 'Y', 'X', 'W', 'V'};    private static final char[] EN_BLUE =    {'U', 'T', 'S', 'R', 'Q', 'P', 'O', 'N', 'M', 'L', 'K', 'J', 'I', 'H',     'G', 'F', 'E', 'D', 'C', 'B', 'A'};    private static final int RED_BEGINNING = 0x4E00;    private static final int RED_ENDING = 0x6936;    private static final int YELLOW_BEGINNING = 0x6937;    private static final int YELLOW_ENDING = 0x846D;    private static final int BLUE_BEGINNING = 0x846f;    private static final int BLUE_ENDING = 0x9fa5;    private static final int CN_ZONE_SPACE = 0x1B37;    private static final int EN_ZONE_SPACE = 0x15;    private static final int EN_UPPER_BEGINNING = 0x40;    private static final int EN_UPPER_ENDING = 0x5A;    private static final int EN_LOWER_BEGINNING = 0x61;    private static final int EN_LOWER_ENDING = 0x7A;    private static final int EN_DIGIT_BEGINNING = 0x30;    private static final int EN_DIGIT_ENDING = 0x39;    //private static final int SYSTEM_HEX = 16;    private UTFBasedEqualLengthCipher()    {    }        /**     * encrypt data     * @param data data     * @param key key     * @return encrypted data     */    public static String encrypt(String data, String key)    {        if (data == null)        {            return null;        }        int length = data.length();        int iKey = keyAscii(key);        int enOffset = (iKey + length) % EN_ZONE_SPACE;//0x15 = 21        int cnOffset = (iKey + length) % CN_ZONE_SPACE;//(0x9FA5 - 0x4E00)/3 = 0x1B37        StringBuffer sb = new StringBuffer();        char[] chars = data.toCharArray();        for (char c : chars)        {            if ((c >= EN_UPPER_BEGINNING && c <= EN_UPPER_ENDING) //@A ~ Z                     || (c >= EN_LOWER_BEGINNING && c <= EN_LOWER_ENDING) //a ~ z                     || (c >= EN_DIGIT_BEGINNING && c <= EN_DIGIT_ENDING))//0 ~ 9             {                char newChar = encryptEN(c, enOffset);                sb.append(newChar);            }            else if (c >= RED_BEGINNING && c <= BLUE_ENDING)            {                char newChar = encryptCN(c, cnOffset);                sb.append(newChar);            }            else            {                sb.append(c);            }        }        return sb.toString();    }    /**     * decrypt data     * @param data data     * @param key key     * @return decrypted data     */    public static String decrypt(String data, String key)    {        if (data == null)        {            return null;        }        int length = data.length();        int iKey = keyAscii(key);        int enOffset = (iKey + length) % EN_ZONE_SPACE;//0x15 = 21        int cnOffset = (iKey + length) % CN_ZONE_SPACE;// (0x9FA5 - 0x4E00)/3 = 0x1B37        StringBuffer sb = new StringBuffer();        char[] chars = data.toCharArray();        for (char c : chars)        {            if ((c >= EN_UPPER_BEGINNING && c <= EN_UPPER_ENDING) //@A ~ Z                     || (c >= EN_LOWER_BEGINNING && c <= EN_LOWER_ENDING) //a ~ z                     || (c >= EN_DIGIT_BEGINNING && c <= EN_DIGIT_ENDING))//0 ~ 9             {                char newChar = decryptEN(c, enOffset);                sb.append(newChar);            }            else if (c >= RED_BEGINNING && c <= BLUE_ENDING)            {                char newChar = decryptCN(c, cnOffset);                sb.append(newChar);            }            else            {                sb.append(c);            }        }        return sb.toString();    }    /**     * encrypt cn     * red[0x4E00 ~ 0x6936]     * yellow[0x6937 ~ 0x846D]     * blue[0x846F ~ 0x9fa5]     * red --> yellow,blue     * yellow --> blue,red     * blue -- > red,yellow     * @param c character     * @param offset offset     * @return new character     */    private static char encryptCN(char c, int offset)    {        if (isInRedCN(c))        {            int position = c - RED_BEGINNING;//position in red zone            char newChar = (char) (YELLOW_BEGINNING + position + offset);            if (isInYellowCN(newChar))            {                return newChar;//mapping in yellow zone            }            else            {                return (char) (BLUE_BEGINNING + (newChar - YELLOW_ENDING));//mapping in blue zone            }        }        else if (isInYellowCN(c))        {            int position = c - YELLOW_BEGINNING;//position in yellow zone            char newChar = (char) (BLUE_BEGINNING + position + offset);            if (isInBlueCN(newChar))            {                return newChar;//mapping in blue zone            }            else            {                return (char) (RED_BEGINNING + (newChar - BLUE_ENDING));//mapping in red zone            }        }        else if (isInBlueCN(c))        {            int position = c - BLUE_BEGINNING;//position in blue zone            char newChar = (char) (RED_BEGINNING + position + offset);            if (isInRedCN(newChar))            {                return newChar;//mapping in red zone            }            else            {                return (char) (YELLOW_BEGINNING + (newChar - RED_ENDING));//mapping in yellow zone            }        }        return c;    }    /**     * red --> yellow,blue     * yellow --> blue,red     * blue -- > red,yellow     * @param c character     * @param offset offset     * @return new character     */    private static char encryptEN(char c, int offset)    {        int index = 0;        if ((index = getIndex(c, EN_RED)) != -1)        {            int newIndex = index + offset;            if (newIndex >= EN_ZONE_SPACE)            {                return EN_BLUE[newIndex - EN_ZONE_SPACE];            }            else            {                return EN_YELLOW[newIndex];            }        }        else if ((index = getIndex(c, EN_YELLOW)) != -1)        {            int newIndex = index + offset;            if (newIndex >= EN_ZONE_SPACE)            {                return EN_RED[newIndex - EN_ZONE_SPACE];            }            else            {                return EN_BLUE[newIndex];            }        }        else if ((index = getIndex(c, EN_BLUE)) != -1)        {            int newIndex = index + offset;            if (newIndex >= EN_ZONE_SPACE)            {                return EN_YELLOW[newIndex - EN_ZONE_SPACE];            }            else            {                return EN_RED[newIndex];            }        }        return c;    }    private static char decryptCN(char c, int offset)    {        char newChar = (char) (c - offset);        if (isInRedCN(c))        {            if (isInRedCN(newChar))            {                return (char) (newChar - RED_BEGINNING + BLUE_BEGINNING);//search in blue zone            }            else            {                return (char) (newChar - RED_BEGINNING + YELLOW_ENDING);//search in yellow zone            }        }        else if (isInYellowCN(c))        {            if (isInYellowCN(newChar))            {                return (char) (newChar - YELLOW_BEGINNING + RED_BEGINNING);//search in red zone            }            else            {                return (char) (newChar - YELLOW_BEGINNING + BLUE_ENDING);//search in blue zone            }        }        else if (isInBlueCN(c))        {            if (isInBlueCN(newChar))            {                return (char) (newChar - BLUE_BEGINNING + YELLOW_BEGINNING);//search in yellow zone            }            else            {                return (char) (newChar - BLUE_BEGINNING + RED_ENDING);//search in red zone            }        }        return c;    }    private static char decryptEN(char c, int offset)    {        int index = 0;        if ((index = getIndex(c, EN_RED)) != -1)        {            int newIndex = index - offset;            if (newIndex >= 0)            {                return EN_BLUE[newIndex];            }            else            {                return EN_YELLOW[EN_ZONE_SPACE + newIndex];            }        }        else if ((index = getIndex(c, EN_YELLOW)) != -1)        {            int newIndex = index - offset;            if (newIndex >= 0)            {                return EN_RED[newIndex];            }            else            {                return EN_BLUE[EN_ZONE_SPACE + newIndex];            }        }        else if ((index = getIndex(c, EN_BLUE)) != -1)        {            int newIndex = index - offset;            if (newIndex >= 0)            {                return EN_YELLOW[newIndex];            }            else            {                return EN_RED[EN_ZONE_SPACE + newIndex];            }        }        return c;    }    private static boolean isInRedCN(char c)    {        if (c >= RED_BEGINNING && c <= RED_ENDING)//[0x4E00 ~ 0x6937]        {            return true;        }        return false;    }    private static boolean isInYellowCN(char c)    {        if (c >= YELLOW_BEGINNING && c <= YELLOW_ENDING)//[0x6938 ~ 0x846e]        {            return true;        }        return false;    }    private static boolean isInBlueCN(char c)    {        if (c >= BLUE_BEGINNING && c <= BLUE_ENDING)//[0x846f ~ 0x9fa5]        {            return true;        }        return false;    }    private static int getIndex(char c, char[] area)    {        for (int i = 0; i < area.length; i++)        {            if (area[i] == c)            {                return i;            }        }        return -1;    }        private static int keyAscii(String key)    {        int ascii = 0;        if (key == null)        {            return 0;        }        char[] chars = key.toCharArray();        for (char c : chars)        {            ascii += c;        }        return ascii;    }}

读书人网 >编程

热点推荐