解析各种加密算法中可能涉及到的 &0xFF 操作

众所周知,内存中的数据都以二进制的形式存储,对于如何把一串字符串写成二进制,我一直迷惑不解,直到我看到下面的信息:

字符串的本质是char的序列,也就是char [ ]。因此,遍历写入每一个char,就完成了写一个字符串的功能!

那么问题又来了,如何把char写成二进制呢?

英语字母有ASCII码,可以把每个字符转换成对应的数字,那么汉字呢,日语呢,韩语呢,泰国语呢?????????

把心放肚子里吧,这个问题前人早就已经解决了。世界上的绝大部分字符都有一张类似于ASCII码表的字符和编码间的映射,那就是Unicode码表。看:

Unicode 字符编码标准是固定长度的字符编码方案,它包含了世界上几乎所有现用语言的字符。有关 Unicode 的信息可在最新版本的 The Unicode Standard 一书中找到,并可从 Unicode 协会 Web 站点(www.unicode.org)中找到。 Unicode 根据要编码的数据类型使用两种编码格式:8 位和 16 位。缺省编码格式是 16 位,即每个字符是 16 位(两个字节)宽,并且通常显示为 U+hhhh,其中 hhhh 是字符的十六进制代码点。虽然生成的 65000 多个代码元素足以用于 编码世界上主要语言的大多数字符,但 Unicode 标准还提供了一种扩展机制,允许编码一百多万个字符。扩展机制使用一对高位和低位代用字符来对扩展字符或补充字符进行编码。第一个(或高位)代用字符具有 U+D800 和 U+DBFF 之间的代码值,而第二个(或低位)代用字符具有 U+DC00 和 U+DFFF 之间的代码值。

unicode码真的可以用2个字节表示世界上的绝大部分字符。

至此,当看到一个char时,我仿佛看到了它背后隐隐欲现的0-65535间的数字,当看到一个String时,我仿佛看到了一串数字!

所以,DataOutputStream.writeChars(str)的源码也就明晰了

[java]  view plain  copy
  1. public final void writeChars(String s) throws IOException {  
  2.         int len = s.length();  
  3.         
  4.         for (int i = 0 ; i < len ; i++) {  
  5.             int v = s.charAt(i);  
  6.             out.write((v >>> 8) & 0xFF);   
  7.             out.write((v >>> 0) & 0xFF);   
  8.         }  
  9.         incCount(len * 2);  
  10.     }

所以除了要遍历一遍string之外,其他的操作Yu DataOutputStream.writeShort(v)的源码没什么区别
[java]  view plain  copy
  1. public final void writeShort(int v) throws IOException {  
  2.         out.write((v >>> 8) & 0xFF);  
  3.         out.write((v >>> 0) & 0xFF);  
  4.         incCount(2);  
  5.     }
至此,就把一串字符串写成二进制了。

但是,你有没有一个疑问????????为什么(v >>> 8) & 0xFF ??为什么(v >>> 0) & 0xFF????不知道你有没有,反正我有。

具体疑问:1 为什么要用无符号的右移? 2 &0xFF不会使数的大小改变,为什么还要 &0xFF?

先科普一下:

0(零)xFF是16进制的255,也就是二进制的 1111,1111

& AND 按位与操作,同时为1时才是1,否则为0.

————位移运算计算机中存的都是数的补码,所以位移运算都是对补码而言的————

<< 左移 右补0

>> 有符号右移 左补符号位,即:如果符号位是1 就左补1,如果符号位是0 就左补0

>>>无符号右移 ,顾名思义,统一左补0

————————————————————————————————————————


要想知道为什么?我们应该想想,我们的目的是干什么的?开始已经讲了:先取高8位写入,再写入低8位.。

0000,0000,0000,0011     3的二进制原码,假设要写入的short字符对应的unicode码是3。

0000,0000,0000,0000      这是">>>8"的结果                        

                          1111,1111       然后再 &0XFF                                                                         

                  0000,0000       最终结果                                                                                    

   这就得到 3的原0000,0000,00000011 的高8位。

    0000,0000,0000,0011        >>>0还是源码本身不变

                              1111,1111        &0XFF                                                                       

                            0000,0011        最终结果 
这就得到了 3的原0000,0000,00000011 的8位。

所以 "&0xFF" 就像计算机中的一把剪刀,当‘&’操作符两边数的bit位数相同时不改变数的大小,只是专门截出一个字节的长度同理,&0x0F呢?得到4bits

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值