java 信息熵 加密

26 篇文章 0 订阅

java 信息熵 加密


在阅读开源代码过程中,发现出现了好多crypto和digest类的代码,发现是加密方面的使用,以前也看过加密原理,但是似是而非没有理解,这次先记录一下java下使用已有的类来完成我们的加密,为后面的深入打下基础(先学会使用再学习原理 :) )

1.MessageDigest

java.security.MessageDigest类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法 简单点说就是用于生成散列码。信息摘要是安全的单向哈希函数,它接收任意大小的数据,输出固定长度的哈希值。

public class DigestLeo {

    //MD5  and  SHA256
    public static final DigestLeo MD5 = new DigestLeo("MD5");
    public static final DigestLeo SHA256 = new DigestLeo("SHA-256");

    //在构造函数中指定算法
    private final String algorithm;

    private DigestLeo(String algorithm) {
        this.algorithm = algorithm;
    }

    /**
     * @param data  输入
     *  产生相应的散列码,数组
     * */
    public byte[] getRaw(String data){
        return getRaw(data.getBytes(StandardCharsets.UTF_8));
    }
    /**
     * 根据相应的算法产生散列码,数组
     * 这个方法和上面的区别仅仅是输入不同,一个数组一个字符串
     * */
    public byte[] getRaw(byte[] data){
        try {
            return MessageDigest.getInstance(algorithm).digest(data);
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        }
    }

    /**
     * string to hex
     * */
    public String getHex(String data){
        return getHex(data.getBytes(StandardCharsets.UTF_8));
    }
    /**
     * bytes to hex
     * */
    private String getHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : getRaw(bytes)){
            sb.append(String.format("%02x",0xFF&b));
        }
        return sb.toString();
    }

    /**
     * 测试代码
     */
    public static void main(String[] args) {
        final String input = "leo";

        DigestLeo d1 = MD5;   //使用MD5算法
        System.out.println(Arrays.toString(d1.getRaw(input)));
        System.out.println(Arrays.toString(d1.getRaw(input)));
        System.out.println(d1.getHex(input));
        System.out.println(d1.getHex(input));

        //同一个算法会产生长度相同的输出
        System.out.println(Arrays.toString(d1.getRaw("leocat")));
        System.out.println(Arrays.toString(d1.getRaw("leocat")));
        System.out.println(d1.getHex("leocat"));
        System.out.println(d1.getHex("leocat"));

        //不同的算法产生的长度不同
        DigestLeo d2 = SHA256;   //使用SHA256算法
        System.out.println(Arrays.toString(d2.getRaw(input)));
        System.out.println(Arrays.toString(d2.getRaw(input)));
        System.out.println(d2.getHex(input));
        System.out.println(d2.getHex(input));
    }
}

使用场景 , 在android中使用SharedPreference会用一个文件名的参数,当我们直接使用字符串时会暴露我们的信息,这时我们就可以使用MD5产生一个字符串的信息熵来作位文件名,或者在保存一些数据到文件中文件名可以这样产生,特点是任意的输入产生特定大小的输出,当然不同的算法(比如MD5和SHA256)会产生不同的长度大小,缺点是单向的,根据信息熵不可以得到输入的数据,这也不算缺点,双向的就是加密,下面来介绍

2.Cipher,此类为加密和解密提供密码功能。

这个demo只是简单的加密,仅仅可以加密的byte数组是16位,再测试过程中遇到了各种异常,在这里暂时加密16位输入

public class CryptoLeo {
    //加密的数组
    private static byte[] raw = new byte[]{'l', 'e', 'o', '-', '-', '-', '-', '-', 'c', 'a', 't', '-', '-', 'o', ':', ')'};
    //instance
    public static final CryptoLeo AES = new CryptoLeo("AES" );
    //AES算法
    private static final SecretKey secret = new SecretKeySpec(raw,"AES" );
    private final String algorithm ;
    public CryptoLeo(String algorithm) {
        this.algorithm = algorithm;
    }

    /**
     * 加密
     * 输入要加密的16位数组
     */
    public byte[] decrypt(byte[] data) throws CryptoException {
        byte[] ret;
        try {
            Cipher cipher = Cipher.getInstance(algorithm+"/CBC/NoPadding");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(new  byte[cipher.getBlockSize()]);
            cipher.init(Cipher.DECRYPT_MODE ,  secret , ivParameterSpec );
            ret = cipher.doFinal(data);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException
                | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e ) {
            throw new CryptoException("decrypt error :" , e);
        }
        return ret;
    }

    /**
     *解密
     * 输入的是加密后的数组
     */
    public byte[] encrypt(byte[] data) throws CryptoException {
        try {
            Cipher cipher = Cipher.getInstance(algorithm+"/CBC/NoPadding");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(new  byte[cipher.getBlockSize()]);
            cipher.init(Cipher.ENCRYPT_MODE , secret , ivParameterSpec);
            return  cipher.doFinal(data);
        } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
            throw new CryptoException("Encrypt error.", e);
        }
    }

    public static class CryptoException extends Exception {
        private CryptoException(String message, Throwable cause) {
            super(message, cause);
        }
    }

    public static void main(String[] args) {
        CryptoLeo c = AES;
        try {
            byte[] datas = AES.decrypt(raw);
            System.out.println(Arrays.toString(datas));
            System.out.println(new String(datas));
            System.out.println(new String(AES.encrypt(datas)));

        } catch (CryptoException e) {
            e.printStackTrace();
        }
    }
}

使用场景 ,结合上面的MessageDigest,在SharedPreference中,文件名有MessageDigest产生,里面重要的数据可以加密后保存,这样在我们需要使用时可以解密获取数据,但是别人即使copy了文件文件中保存的是加密后的数据也无法破解

3.学习体悟

通过阅读开源代码,一点一点慢慢进步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
权法(Entropy Weight Method)是一种用于多指标综合评价的方法,可以用于决策问题中权重的确定。在Java中实现权法,可以按照以下步骤进行: 1. 定义指标和样本数据:首先,确定需要评价的指标和相应的样本数据。假设有n个指标和m个样本数据。 2. 数据预处理:对于每个指标,需要将原始数据进行标准化处理,使得不同指标的数据具有可比性。可以采用最大-最小标准化、Z-score标准化等方法。 3. 计算值:对于每个指标的每个样本数据,计算其相对值。相对值可以通过以下公式计算: ![公式1](https://img-blog.csdnimg.cn/20211122171656481.png) 其中,x_ij表示第i个指标的第j个样本数据,p_ij表示x_ij在所有样本数据中的相对比例。 4. 计算权向量:根据计算得到的相对值,可以计算权向量。权向量可以通过以下公式计算: ![公式2](https://img-blog.csdnimg.cn/20211122171801275.png) 其中,w_i表示第i个指标的权重,e_i表示第i个指标的相对值。 5. 归一化权重:对于计算得到的权向量,进行归一化处理,使得所有权重之和为1。可以通过以下公式计算: ![公式3](https://img-blog.csdnimg.cn/20211122171914738.png) 其中,w_i'表示归一化后的第i个指标权重,w_i表示第i个指标的原始权重。 通过以上步骤,就可以得到各个指标的权重,从而进行多指标综合评价。 希望以上内容对你有帮助!如有疑问,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值