`
jerry1985
  • 浏览: 30349 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

基于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;
    }
}
  • 大小: 18.7 KB
分享到:
评论

相关推荐

    电子政务-全数字电视广播加解扰电路.zip

    在电子政务中,全数字电视广播加解扰电路技术可应用于公共信息传播、教育服务、应急通信等多个场景。例如,政府可以通过加密的频道发布政策公告,确保信息安全传递;或者提供付费的在线培训课程,利用智能卡管理用户...

    数字电视条件接收技术中加解扰算法研究

    ### 数字电视条件接收技术中加解扰算法研究 #### 一、条件接收系统概述 数字电视技术的兴起改变了传统模拟电视的传播方式,而条件接收技术(Conditional Access, CA)则是数字电视技术中的一项核心内容。该技术...

    dtv 公共解扰算法

    标题中的“dtv公共解扰算法”指的是在数字电视(DTV)系统中用于解密和解码加密节目的算法。这种技术是数字广播系统的重要组成部分,确保付费电视服务的版权得到保护,只有合法用户能够观看特定节目。MPEG-2是数字...

    电子功用-对总线进行加解扰的装置和方法、集成电路芯片

    例如,PCI Express使用8b/10b编码,这是一种混合的加解扰和编码方式,旨在保持直流平衡,减少EMI,并提供错误检测功能。 总的来说,电子设备中的总线加解扰技术和集成电路芯片的设计是现代电子系统中不可或缺的部分...

    电子功用-对总线进行加解扰的装置、集成电路芯片

    3. 总线加解扰机制:加解扰通过在数据传输前对原始数据进行特定的算法处理,比如使用加密算法,使得数据在总线上呈现的形式与原始数据不同,增加了数据的安全性。接收端则使用相应的解扰算法还原数据,确保数据的...

    行业分类-设备装置-基于加扰器频率转移算法的数据序列处理方法.zip

    本主题聚焦于“基于加扰器频率转移算法的数据序列处理方法”,这是一种用于提升信号处理效率和抗干扰能力的技术。该算法的核心在于利用加扰器和频率转移策略来改善数据序列的传输质量和安全性。 首先,我们需要理解...

    电子功用-有线电视加解扰控制技术

    有线电视加解扰控制技术是现代有线电视系统中不可或缺的一部分,主要用于保障电视信号的安全传输,防止未经授权的用户非法接收付费电视节目。这一技术在数字电视时代尤为重要,因为其涉及的内容不仅仅是传统的模拟...

    行业资料-电子功用-具有1394解扰模块的为电缆准备的数字系统的说明分析.rar

    2. **解扰模块的原理**:详述解扰模块如何工作,可能包括了解扰过程中的算法、数据解码、错误校验等方面,这些是保证数据在经过电缆传输后能够正确解码的关键步骤。 3. **数字系统设计**:讨论如何将1394解扰模块...

    模拟有线电视加解扰技术方案.pdf

    4. 加解扰技术的关键组件:通常来说,一个加解扰系统会包括几个关键的组件:加扰器、加密算法、安全密钥管理、解扰器、用户授权管理系统等。这些组件协同工作以确保信号的安全传输。 5. 安全性和破解风险:虽然加解...

    电子功用-收费电视计费装置加扰器及其解扰计费器

    行业资料-电子功用-收费电视计费装置加扰器及其解扰计费器

    8-bits并行扰码器和解扰器 VHDL

    8位并行扰码器和解扰器是数字通信系统中的关键组件,它们主要用于数据编码,以提高数据传输的可靠性。在本项目中,这些组件是使用硬件描述语言VHDL设计的,这是一种用于创建数字逻辑系统的编程语言,特别适用于FPGA...

    加扰与解扰

    在这个项目中,VHDL被用来编写加扰和解扰算法的代码,这些代码可以在FPGA(Field-Programmable Gate Array)或ASIC(Application-Specific Integrated Circuit)等硬件平台上实现。 Modelsim是一款流行的仿真软件,...

    matlab仿真程序源码 音频加解扰

    matlab仿真程序源码 音频加解扰 源码分享,用matlab2014进行仿真

    TD-LTE系统中基于FPGA的解调与解扰的仿真和实现.pdf

    综上所述,TD-LTE系统中的基于FPGA的解调与解扰技术的研究,不仅涉及到通信理论和算法设计,还包括了硬件实现和系统集成,是通信工程中的一个跨学科领域。这项技术对于推动移动通信技术的发展,提高网络的传输速率和...

    行业资料-交通装置-一种汽车扰流板.zip

    行业资料-交通装置-一种汽车扰流板.zip

    linux csa实时解扰工具

    Realtime decoding needs ~1GhZ , API for CWs is included , Realtime playback with mplayer possible. CSA is an abbreviation for ...通过csa公共解扰算法对ts流解扰。这个是最初的版本,比较简单,容易集成。

    完整word版-CRC16、扰码、解扰码器并行方案原理和Verilog-HDL程序设计解读.doc

    该程序设计主要包括 CRC_16 校验码的并行编码程序和扰码/解扰码器的并行算法程序。通过该程序设计,可以实现快速的数据传输和高效的差错控制。 五、结论 本文总结了 CRC16、扰码、解扰码器并行方案的原理和 ...

    ECShop v2.6.2 beta2 UTF-8.rar

     [变更] 数据库备份文件命名采用时间 扰码方式  [变更] 报价单不显示已下架商品  [变更] 能够重置会员密码  [变更] 购物车商品数量变更时提示用户点击更新购物车  [变更] 生成商品代码时增加行数的选项  ...

    行业资料-交通装置-一种汽车扰流板的成形工艺.zip

    行业资料-交通装置-一种汽车扰流板的成形工艺.zip

    电子政务-同步头恢复电视解扰器的加法器.zip

    内容可能涵盖了加法器的不同类型(如二进制加法器、超前进位加法器等)、同步头恢复的算法、电视解扰器的加密技术,以及它们在电子政务系统中的具体部署和优化策略。 总的来说,这份压缩包文件提供了关于电子政务...

Global site tag (gtag.js) - Google Analytics