byte[]与String互转引发的血案

String s = "HelloWorld";
byte[] b = s.getBytes();
System.out.println(new String(b));

看到上面的代码,可能有同学会问了,这不就是JAVA的基本操作吗,你老张有什么好讲的?

既然这样,老张要考考大家,猜一下下面的代码执行之后会输出怎样的结果。

public class Hello {
    public static void main(String[] args){
        String src = "HelloWorld";
        String dest = encrypt(src);
        System.out.printf("原来字符转为字节的长度为:%d\n", src.getBytes().length);
        System.out.printf("加密字符转为字节的长度为:%d\n", dest.getBytes().length);
    }


    /*为了String进,String出,做了一次封装*/
    private static String encrypt(String s){
        byte[] b = encrypt(s.getBytes());
        return new String(b);
    }


    /*这里只是用位移演示加密,字节进,字节出*/
    private static byte[] encrypt(byte[] byteArr){
        for (int i=0; i<byteArr.length; i++){
            byteArr[i] <<= 1;
        }
        return byteArr;
    }
}

现在揭晓答案:

原来字符转为字节的长度为:10
加密字符转为字节的长度为:26

不知道各位同学有没有猜对,说来惭愧,老张刚刚踩过这个坑。

事情的起因是这样的,由于Java没有内置的RC4加密,老张需要自己封装实现,实现的过程中用到了字节和字符的互相转换。因为RC4只是在针对的byte[]上进行位移操作,所以其输入输出的字节长度应该是相等的。但是老张为了使加密能够应用于字符串,用字符串对加密方法做了一层封装。问题就出在这一层封装上。

且听老张给你慢慢道来。

什么是字节?

位是计算机内部的最小数据储存单位,8位就组成了1字节,也就是java中的byte。

什么是字符?

字符是指字母、数字、特殊符号的集合,也就是java中的char和String。

字节怎么就变成了字符?

答案是字符编码。比较出名的字符编码是ascii、gb2312、utf-8等。其中ascii和gb2312是定长字符编码,一个字符分别占用1字节、2字节,而utf-8是变长字符编码,最短为1字节,最常为4字节。

以ascii为例,字母A在计算机中的存储为0b0100 0001。

到这里可能有同学已经知道老张一开始天真在哪里了?

如果只是字符串转为字节流之后又接着转为字符串也没什么问题。老张天真就天真在对utf-8得到的字节流做了位移操作之后,还期望能够用utf-8重新解析字节流。

敲黑板:Java中String内置的public String(byte[] bytes)和public byte[] getBytes()对于不合法的utf-8字节流在解析时会增删字节。

希望各位同学引以为戒!

最后如何避免在使用加密算法时出现字节和字符的异常转化,欢迎各位同学能够留言,有需要RC4加密代码的也可以在后台留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值