判断二进制数据中第n位是否为1
N:待判断的二进制数
B:待判断的位(右往左,索引从1开始)
结果:((N>>(B-1)))&1
parseInt('111',2) # 7
十进制转二进制 21..toString(2) 得`10101`
二进制位1的个数
let count = 0;
while (n >0 ) {
n &= (n-1);
count++;
}
按位与运算 |
其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。
例如:
9|5
可写算式如下:
00001001
|
00000101
=00001101
parseInt('00001101',2) => 13
按位异或运算
按位异或运算符“^”是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。
例如
9^5
可写成算式如下:
00001001
^
00000101
=00001100
(十进制为12)
parseInt('00001100',2) => 12
求反运算
求反运算符~为单目运算符,具有右结合性。 其功能是对参与运算的数的各二进位按位求反。
例如
求反运算为:
~(1001)
结果为:
0110
<< 左移动多少位
2<<3 表示2的各二进制位左移3位, 2的二进制'00000010' (2..toString(2)), 左移动3位的二进制变为 '00010000',转十进制结果为 16 (parseInt('00010000',2)); 也可以理解该值左移n位就是该值乘以2的n次方:如2乘以2的3次方(2*2*2*2)
ascii 码编号转字符
'='.charCodeAt(0) => 61 # 字符=号对应的ascii码 61
String.fromCharCode(61) => '=' # 将ascii编码为61转字符 "="
var a = "我";
console.log(a.charCodeAt()); //25105
console.log(a.charCodeAt().toString(2)); //110001000010001
比特 bit 字节 byte ASCII码 Unicode 关系
一个字节是由两位16进制数组成。
十六进制数转换成二进制数:把每一个十六进制数转换成4位的二进制数,就得到一个二进制数
例子:
十六进制 0xA5
方法一: A*16的1次方+5*16的0次方得出十进制。10(0xA为十)*16+5*1=165 然后拿十进制再转二进制(165).toString(2) // "10100101"
方法二:16进制中A用二进制表是多少?A代表十进制数10 ,(0xA).toString(2) 就是二进制的 1010, 5的二进制(0x5).toString(2) "101"转换成4位的二进制数,前补齐0得 "0101", 拼接二进制位得 "1010 0101"
二进制转十进制 parseInt('10100101', 2) // 165 0xA5的十进制刚好也是165
(165).toString(16) // 十进制165转16进制位 "0xa5" 0x表示十六进制
二进制数字与十六进制数字的对应关系如下:0000 -> 0、0001 -> 1、0010 -> 2、0011 -> 3、0100 -> 4、0101 -> 5、0110 -> 6、0111 -> 7、1000 -> 8、1001 -> 9、1010 -> A、1011 -> B、1100 -> C、1101 -> D、1110 -> E、1111 -> F
因此,1个16进制数对应4个二进制数位,2个16进制数位对应8个二进制数位,及1个字节(8个比特位)
puffer = b'\x00\x00(\x00' # 4个字节
struct.unpack('I', puffer) # I表示整数, 整数占4个字节 解码= 2621440
# 底层算法
(puffer[0] | puffer[1] << 8 | puffer[2] << 16 | puffer[3] << 24);
8,16,24 表示左移动 8的1,2,3次方
# puffer[0] = 0
# puffer[1] = 0
# puffer[2] = 40
# puffer[3] = 0
带入计算 (0 | 0<<8 | 40 << 16 |0 << 24)= 2621440
40左移动16 表示40*2的16次方
ArrayBuffer,字符串互转
// ArrayBuffer转为字符串,参数为ArrayBuffer对象
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
// 字符串转为ArrayBuffer对象,参数为字符串
function str2ab(str) {
var buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节
var bufView = new Uint16Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
ASCII码中,一个英文字母(不分大小写)占一个字节byte的空间,一个中文汉字占两个字节的空间
UTF-8编码中,一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。
Unicode编码中,一个英文等于两个字节,一个中文(含繁体)等于两个字节。
符号:英文标点占一个字节,中文标点占两个字节。举例:英文句号“.”占1个字节的大小,中文句号“。”占2个字节的大小。
UTF-16编码中,一个英文字母字符或一个汉字字符存储都需要2个字节(Unicode扩展区的一些汉字存储需要4个字节)。
UTF-32编码中,世界上任何字符的存储都需要4个字节。
字符串转16进制
var b = 'a'.charCodeAt(0) // 字符串a的结果为十进制 97 的ASCII码
var c = b.toString(16) // 十进制97转为16进制结果 61 十六进制表示为 0x61
var d = c.toString(2) // 16进制转为二进制结果 1100001
var e = parseInt("1100001",2) // 二进制转为十进制ASCII码 为97
var f = String.fromCharCode(e) // 十进制 97 的ASCII码转字符串为 a
'a'(a字符占一个字节) -> 97(十进制 ASCII码) -> 0x61(十六进制) -> '01100001'(二进制,8比特位一个字节)
Unicode 编解码
// 解码
// "你好" 对应Unicode 编码为 "\\u4f60\\u597d" 其中4f60 为16进制(Unicode一个中文占两个字节), 0x4f60 转十进制
var a = parseInt("0x4f60",16) // 等于十进制 20320
String.fromCharCode(a) // 20320 十进制unicode字符为'你'
// 编码
var a = "好".charCodeAt(0) // 转为十进制unicode码'22909'
var b = a.toString(16) // 转为十六进制unicode 597d
var u = `\\u${b}` // '\\597d'
字符编解码
字符'b', 'i', 't', 's' 对应ASCII码 分别为 98,105,116,115, 每个字符占一个字节(8比特位)共四个字节,编码成一个整数 98<<24|105<<16|116<<8|115<<0, 24,16,8,0分别为左右3字节(3 x 8),2字节(2 x 8),1字节(1 x 8),0字节(0 x 8)比特位, 等于1651078259。
示例
'你'.charCodeAt(0).toString(16) 转unicode 16进制表示
unicode 20320 => 4f60 占两个字节,2个16进制字符为一个字节
0x4f <<8|0x60 <<0 = 20320
解码
字符'b', 'i', 't', 's' 字节表示 []byte{98, 105, 116, 115}
一共4字节, 编码 98<<24|105<<16|116<<8|115<<0
分别左移3(3*8 =24比特位),2,1,0字节后成 1651078259整数, 解码时只需要将整数 按位右移>>, 0xff
为ASCII码范围,ASCII码共有256个字符 ASCII码占用一个字节,可以有0~255共256个取值
1651078259>>24 // 98
1651078259>>16 & 0xff //105
1651078259>>8 & 0xff // 116
1651078259>>0 & 0xff // 115
中文转成16进制 菲
转成十进制 '菲'.charCodeAt() => 33778, (33778).toString(16) => 83f2.
或者 33778>>8 & 0xff =131
, 33778>>0 & 0xff =242
中文unicode占两个字节,所以右移2次 . 131 和 242的16进制表示为0x83, 0xf2, 拼接后得到0x83f2, 16进制每两位为一个字节,
Unicode 和 UTF-8 之间的区别
Unicode 是字符集。 UTF-8 是编码。
Unicode 是有唯一的十进制数字(代码点)的字符列表。 A = 65,B = 66,C = 67,...。
这个十进制数字列表表示字符串 "hello":104 101 108 108 111
编码是将这些数字转换为二进制数字以存储在计算机中的方式:
UTF-8 编码将像这样(二进制)存储 "hello":01101000 01100101 01101100 01101100 01101111,01101000 => parseInt('01101000', 2) 将二进制字符变为unicode码 104 => String.fromCharCode(104) 将unicode码转为字符 h
编码将数字转换为二进制。字符集将字符转换为数字。
参考: mp.weixin.qq.com/s?__biz=MzU… 二进制读写:www.jb51.net/article/147…