二进制;16进制; Byte , Python的bytes类; Base64数据编码; Bae64模块;
- 二进制
- 位操作(wiki)
- Byte字节
- 互联网数据处理:Base64数据编码
- Python的模块Base64
- 16进制简介
- python: bytes对象
- 字符集介绍:ascii
二进制简介:
In mathematics and digital electronics, a binary number is a number expressed in the base-2 numberal system or binary numeral system, which uses only two symbos: zero(0) and one(1)。
在数学和数字电路(集成电路),二进制数字是以2个数字为基础的系统(或二进制数字系统)表示的数字,它只使用2个符号0和1。
数字电子电路中,逻辑门的实现直接应用了二进制,因此现代的计算机和依赖计算机的设备里都用到二进制。
每个数字代表一个bit(Binary digit)
四则运算:
计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。
计算的效率:位操作(位运算)
因为计算机的数据存储只有0和1,为了效率,直接对二进制数字进行计算,无需先把二进制的数转换为十进制再进行加减乘除。
这就是汇编语言计算速度快于高级语言(比如C语言)的原因。当然代码的可阅读性就降低了。
➕法的例子,根据上面的四则运算规则,就可以通过二进制数进行计算了。
:
:
————————————————————
:
乘法的例子
int a = 3;
int b = 2; #后面的b分别为4, 8
int c = a * b; 3: 0 0 0 0 0 0 1 1 * 2
————————————————————
6: 0 0 0 0 0 1 1 0 ********************************************* 3: 0 0 0 0 0 0 1 1 * 4
————————————————————
12: 0 0 0 0 1 1 0 0 ********************************************* 3: 0 0 0 0 0 0 1 1 * 8
————————————————————
24: 0 0 0 1 1 0 0 0
通过上面的规律可知,a*b,
如果b满足2^N的时候,就相当于把a的二进制数据向左边移动,移动的位数是N,这叫做移位运算,是位运算的一种。
所以用代码可以这么表示,a << N。
本例子是 3<<1, 3<<2, 3<<3。
如果b不等于2^N,编译器会将b拆分。例子:
int a = 15;
int b = 13; => int b = (4 + 8 + 1)
int c = a * b;
运算转换为 15 * 4 + 15 * 8 + 15 * 1, 进行位运算,代码就是:
15 << 2 + 15 << 3 + 15 << 0
除法和乘法的原理相同,不过是改成右移动了。
参考:https://juejin.im/post/5a5886bef265da3e38496fd5
十进数转成二进数
例子:十进制数:59.25。
59是整数部分,0.25是小数部分。分别使用不同的计算方式:
- 整数部分:
- 进行带余除法运算。得到一个整数和一个余数。
- 对得到的整数继续进行第一步操作。直到步骤N得到商数为0。(商数:除法运算的结果。一般是指整数部分)
- 把上面多次带余除法运算得到的余数按照步骤从后往前排列组合。方法:(N代表第N步骤的余数):N组合N-1组合..1。组合得到就是二进制的整数数字部分。本例得到111011。
- 小数部分:
- 对小数部分乘以2,得结果x,取x的整数部分。
- 对结果x乘以2,取其整数部分。如此反复,直到乘法得到的数字的小数部分全部为0为止。
- 读取所有乘法计算后得到的数字的整数部分,从第一步到最后一步组合。得到二进制的小数部分。本例是01.
整数部分:
59 ÷ 2 = 29 ... 1
29 ÷ 2 = 14 ... 1
14 ÷ 2 = 7 ... 0
7 ÷ 2 = 3 ... 1
3 ÷ 2 = 1 ... 1
1 ÷ 2 = 0 ... 1
小数部分:
0.25×2=0.5
0.50×2=1.0
最后得到二进制数字59.25(10) = 111011.01(2)
二进位转成十进位
整数部分的转换方法:个位数乘以2的0次幂, 然后10位数乘以2的1次幂,如此每加一位那么2的次幂就加1,最后把得到数字相加就是十进制数字。
- 1001012 = [ ( 1 ) × 25 ] + [ ( 0 ) × 24 ] + [ ( 0 ) × 23 ] + [ ( 1 ) × 22 ] + [ ( 0 ) × 21 ] + [ ( 1 ) × 20 ]
- 1001012 = [ 1 × 32 ] + [ 0 × 16 ] + [ 0 × 8 ] + [ 1 × 4 ] + [ 0 × 2 ] + [ 1 × 1 ]
- 1001012 = 3710
非整数部分的转换方法:利用负次幂。例如0.01(2)
0 × 2−1 | (0 × 1⁄2 = 0) | 加 |
1 × 2−2 | (1 × 1⁄4 = 0.25) |
得到十进制数字:0.25
位操作(wiki)Bitwise operation
位操作是程序设计中对位模式(bit patterns)或二进制数(binary numerals)的一元和二元操作。
在许多古老的微处理器上(simple low-cost processors),位运算比加减运算略快,比乘法运算要快很多, 在除法上明显的快。
现代处理器执行加法和乘法和位运算一样快,这是因为它们采用longer instruction pipelines and other architectural design choices, 但位操作降低资源的使用更节能。
位云算符:Bitwise operators
- not 取反: ~ 取反是一元运算符,对一个二进制数的每一位执行逻辑反操作。使数字1成为0,0成为1。
- or 按位或 | 处理两个长度相同的二进制数,两个相应的二进位中只要有一个为1,该位的结果值为1。
- xor 按位异或 ^
- 对等长二进制模式或二进制数的每一位执行逻辑异或操作。操作的结果是如果某位不同则该位为1,否则该位为0。
- 2020-1-12再理解:按位置对2个数比较,有差异则为真(1),无差异则为假(0)
- and 按位与 & 处理两个长度相同的二进制数,两个相应的二进位都为1,该位的结果值才为1,否则为0。
按位异或:
汇编语言的程序员们有时使用按位异或运算作为将寄存器的值设为0的捷径。用值的自身对其执行按位异或运算将得到0。并且在许多架构中,与直接加载0值并将它保存到寄存器相比,按位异或运算需要较少的中央处理单元时钟周期。
0101
XOR 0011
= 0110
移位 Bit shifts
移位是一个二元运算符,用来将一个二进制数中的每一位全部都向一个方向移动指定位,溢出的部分将被舍弃,而空缺的部分填入一定的值。在类C语言中,左移使用两个小于符号"<<"表示,右移使用两个大于符号">>"表示。
算数移位 Arithmetic shift(具体见wiki)
- ⬅️,补0
- ➡️,复制。
逻辑移动 Logical shift
上一章讲二进制的乘法运算,就是逻辑移动。利用的是二进制数的特性。
应用逻辑移位时,移位后空缺的部分全部填0。
- 位移就是补0。zeros are shifted in to replace discarded bits。左位移,逻辑移动和算数移动一样。
- 但是右移动,逻辑移动是插入0bit,而算数位移是复制bit。
#乘法运算1*(2^3)
0001(十进制1)
<< 3(左移3位)
= 1000(十进制8) # 除法运算10/(2^2), 移动第2次,得到2,去掉了小数部分。
1010(十进制10)
>> 2(右移2位)
= 0010(十进制2)
Circular shiift(具体见英文wiki)
Byte
字节(港澳台叫元组,Byte), 是数字信息的单位,最常见的是8个bits组成一个byte。
从历史上看,byte是bit的数量,bit用于在计算机上给文本字符编码。基于这个原因,在计算机学,byte是最小的内存地址单位。
- Byte缩写B.
- Bit缩写b。
1个8b的Byte,最大是11111111,转换为十进制是255。因此范围是0~255。
ASCII码:一个英文字母占一个Byte.即8个bit。
Base64(wiki)
Base64是一种基于64个可打印字符来表示二进制数据的表示方法。
可打印字符包括字母A-Z
、a-z
、数字0-9,和2个特别字符+,/。合计64个。
每6个bit表示一个Base64字符。
Base64索引表:
数值 | 字符 | 数值 | 字符 | 数值 | 字符 | 数值 | 字符 | |||
---|---|---|---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w | |||
1 | B | 17 | R | 33 | h | 49 | x | |||
2 | C | 18 | S | 34 | i | 50 | y | |||
3 | D | 19 | T | 35 | j | 51 | z | |||
4 | E | 20 | U | 36 | k | 52 | 0 | |||
5 | F | 21 | V | 37 | l | 53 | 1 | |||
6 | G | 22 | W | 38 | m | 54 | 2 | |||
7 | H | 23 | X | 39 | n | 55 | 3 | |||
8 | I | 24 | Y | 40 | o | 56 | 4 | |||
9 | J | 25 | Z | 41 | p | 57 | 5 | |||
10 | K | 26 | a | 42 | q | 58 | 6 | |||
11 | L | 27 | b | 43 | r | 59 | 7 | |||
12 | M | 28 | c | 44 | s | 60 | 8 | |||
13 | N | 29 | d | 45 | t | 61 | 9 | |||
14 | O | 30 | e | 46 | u | 62 | + | |||
15 | P | 31 | f | 47 | v | 63 | / |
原理
63(2) = 111111(2)
所以只需6个bit就可以表示64个字符了。
例子:
编码"man"
文本 | M | a | n | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ASCII编码 | 77 | 97 | 110 | |||||||||||||||||||||
二进制位 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
索引 | 19 | 22 | 5 | 46 | ||||||||||||||||||||
Base64编码 | T | W | F | u |
Man的ASCII编码对应十进制数字是77,97,110,转换为二进制数字见上图。共有24bit。
把上面的24个二进制数字分割成4部分,每部分6bit。比如第一部分的二进制码:010011。
4个部分转换为十进制是19,22,5,46。
使用Base64编码,查看编码表,对应的字符是TWFu。
本例子,Base64算法将3个字节的ASCII编码转换为了4个字符的编码。
相比较ASCII码,Base64更节省空间。ASCII3个Byte,可以存3个字母,但Base64用3个Byte可以存4个字母。
特殊的情况:编码"a"或“aa”这种不足3个字符的文本字符串怎么办?
答案:很简单,为不足的二进制位后补上0即可。
用途
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME的电子邮件及XML的一些复杂数据。
(更节省空间)
在URL中的使用
因为Base64更省空间,所以用于网络传输数据上有优势。在HTTP环境下被经常使用。因为数据库对%符号占用的问题。出现了改进版的Base64。但原理都一样。
Python的base64模块
此模块提供了将二进制数据编码为可打印的 ASCII 字符以及将这些编码解码回二进制数据的函数。
它为 RFC 3548 指定的 Base16, Base32 和 Base64 编码以及已被广泛接受的 Ascii85 和 Base85 编码提供了编码和解码函数。
它支持所有 base-64 字母表 (普通的、URL 安全的和文件系统安全的)。
base64.b64encode(s)
对bytes-like objects进行编码,并返回编码后的bytes对象。
base64.urlsafe_b64encode(s)
使用的是URL和文件系统安全的字母表,用-和_代替标准Base64的+和/。
例子:
>>> base64.b64encode(b'\xfb\xef\xff')
b'++//'
>>> base64.urlsafe_b64encode(b'\xfb\xef\xff')
b'--__'
bytes对象
是由单个字节构成的不可变序列。
表示 bytes 字面值的语法与字符串字面值的大致相同,只是添加了一个 b
前缀.
例子:
一个能处理去掉=
的base64解码函数:
import base64 def safe_base64_decode(s):
length = len(s)
r = length % 4
if r == 0:
return base64.b64decode(s)
i = 1
while i <= r:
s = s + b"="
i += 1
return base64.b64decode(s) # 测试:
assert b'abcd' == safe_base64_decode(b'YWJjZA=='), safe_base64_decode('YWJjZA==')
assert b'abcd' == safe_base64_decode(b'YWJjZA'), safe_base64_decode('YWJjZA')
print('ok')
⚠️备注:
去掉=
后怎么解码呢?因为Base64是把3个字节变为4个字节,所以,Base64编码的长度永远是4的倍数,因此,需要加上=
把Base64字符串的长度变为4的倍数,就可以正常解码了。
另外baes64的方法是对Byte类对象编码和解码,所以字符串前面带字符b。
16进制(wiki)
十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制。
用数字0到9和字母A到F表示,其中:A~F相当于十进制的10~15,这些称作十六进制数字。
在历史上,中国曾经在重量单位上使用过16进制,比如,规定16两为一斤。
现在的16进制则普遍应用在计算机领域,这是因为将4个Bit化成单独的16进制数字不太困难。1个字节(Byte)有8个bit,表示成2个连续的16进制数字。可是,这种混合表示法容易令人混淆,因此需要一些字首、字尾或下标来显示。
例:
F16的二进制表示为1111(2)
016的二进制表示为0000(2)
表示方法
C语言、C++、Shell、Python、Java语言及其他相近的语言使用字首“0x”,例如“0x5A3”。
最常用(或常见)表示十六进制数值的方式是将 '0x' 加在数字前,或在数字后加上小字 16。例如 0x2BAD 和 2BAD16 都是表示十进制的11181(或1118110), 用二进制表示则需要2个Bytes(16个bit): 0010101110101101。
十六进制的转换
十进制转十六进制,采用余数定理分解。类似十进制转换为2进制。除数改为16.
例如将487710转成十六进制:
4877÷16=304....13(D)
304÷16=19....0
19÷16=1....3
1÷16=0....1
这样就计到487710=130D16
编程中的函式
Python:
int('ff', 16) #255,把ff16转换为十进制数字255
hex(255) #0xff, 转换为16进制,用前标记符号0x表示
Python: bytes对象
是由单个字节构成的不可变序列。
bytes 函数返回一个新的 bytes 对象,该对象是一个 0 <= x < 256 区间内的整数不可变序列。它是 bytearray 的不可变版本。
bytes 对象只负责以字节(二进制格式)序列来记录数据。
如果采用合适的字符集,字符串可以转换成字节串;反过来,字节串也可以恢复成对应的字符串。
由于 bytes 保存的就是原始的字节(二进制格式)数据,因此 bytes 对象可用于在网络上传输数据,也可用于存储各种二进制格式的文件,比如图片、音乐等文件。
转化方法
1. 表示 bytes 字面值的语法与字符串字面值的大致相同,通过添加了一个 b
前缀,构建字节串。
2.class bytes([source[, encoding]])
参数
- source: 为整数,返回一个长度为source的初始化bytes对象。
- 如果 source 为字符串,则按照指定的 encoding 将字符串转换为字节序列
- 如果 source 为可迭代类型,则元素必须为[0 ,255] 中的整数;否则会报告❌ValueError: byte must be in range(0, 256)
- 如果没有输入任何参数,默认就是初始化数组为0个元素。
bytes 字面值中只允许 ASCII 字符(无论源代码声明的编码为何)。
创建bytes对象的2种方式:
- b"xxx",用字面量的方式创建
- bytes()函数创建。例子:bytes(range(10)),创建由整数组成的可迭代对象。
如果使用字符串,需要指定编码方式:
b = bytes('h',encoding='ascii') #利用内置bytes方法,将字符串转换为指定编码的bytes
>>> bytes("h",encoding='ascii')
b'h'
>>> bytes.decode(b'\x68') #把b'\x68'解码得到ascii对应的符号
'h'
3.
调用字符串的encode()函数来转化成bytes对象的字节串。
bytes.decode()可以反向转化成字符串。
>>> b'\x68'.decode()
'h'
>>> "h".encode()
b'h'
例子
1.使用bytes()函数,例子:
十进制99的16进制是0x63,对应的ascii码是小写字母c:
64(10) = 0x40(16) , 对应的ascii码是@
>>> a = bytes([64,99])
>>> a
b'@c'
2.
>>> b1 = bytes()
>>> b2 = b''
>>> b3 = b'hello'
>>> b3
b'hello'
>>> b3[0]
104
>>> b3[2:4]
b'll'
>>> b4 = bytes('你好,Python!', encoding='utf-16')
>>> b4
b'\xff\xfe`O}Y\x0c\xffP\x00y\x00t\x00h\x00o\x00n\x00!\x00'
备注:ascii字符集表
计算机底层并不能保存字符,但程序总是需要保存各种字符的,那该怎么办呢?
计算机“科学家”就想了一个办法:为每个字符编号,当程序要保存字符时,实际上保存的是该字符的编号;当程序读取字符时,读取的其实也是编号,接下来要去查“编号一字符对应表”(简称码表)才能得到实际的字符。
所谓的字符集,就是所有字符的编号组成的总和。早期美国人给英文字符、数字、标点符号等字符进行了编号,他们认为所有字符加起来顶多 100 多个,只要 1 字节(8 位,支持 256 个字符编号)即可为所有字符编号一一这就是 ASCII 字符集。
后来各个国家都为本国文字进行编码,为了解决兼容问题,使用了2个字节(16位,65536个字符编码)的字符集--Unicode字符集。实际使用的 UTF-8, UTF-16 等其实都属于 Unicode 字符集。
二进制;16进制; Byte , Python的bytes类; Base64数据编码; Bae64模块;的更多相关文章
- asp.net AES加密跟PHP的一致,将加密的2进制byte[]转换为16进制byte[] 的字符串获得
<?php class AESUtil { public static function encrypt($input, $key) { $size = mcrypt_get_block_siz ...
- Android选择/拍照 剪裁 base64/16进制/byte上传图片+PHP接收图片
转载请注明出处:http://blog.csdn.net/iwanghang/article/details/65633129认为博文实用,请点赞,请评论,请关注.谢谢! ~ 老规矩,先上GIF动态图 ...
- WPF 16进制byte输入框
在WPF中,针对byte类型的输入控件可以选用 XCEED 的免费库中的 Xceed.Wpf.Toolkit.ByteUpDown(可从nuget获取). 若要使该控件在界面上以16进制显示byte, ...
- C语言:将16进制字符串转化为int类型值
将16进制字符串值转换为 int 整型值 此例中用 "1de" 作为测试字符串,实现代码如下: #include <stdio.h> #include <stdl ...
- c# 16进制byte转成int
]; Ratedata=System.BitConverter.GetBytes(FreResultTBoxValue); 上面这个 FreResultTBoxValue 变量是int,系统中自带in ...
- python2/3中 将base64数据写成图片,并将图片数据转为16进制数据的方法、bytes/string的区别
1.python2将base64数据写成图片,并将数据转为16进制字符串的方法 import binascii img = u'R0lGODlhagAeAIcAAAAAAAAARAAAiAAAzABE ...
- python - 2 8 16进制/颜色/字符编码
1.二进制 八进制 十六进制 二进制: bin() 0b10010八进制: oct() 0o10十进制: 1-100十六进制: hex() 0X53 BH 十进制转2, 8,16进制: >> ...
- golang中字符串、bytes类型切片、16进制字符串之间的转换
func main() { // 字符串转bytes类型 name := "马亚南" fmt.Println(name) // 马亚南 bName := []byte(name) ...
- Java 将字节数组转化为16进制的多种方案
很多时候我们需要将字节数组转化为16进制字符串来保存,尤其在很多加密的场景中,例如保存密钥等.因为字节数组,除了写入文件或者以二进制的形式写入数据库以外,无法直接转为为字符串,因为字符串结尾有\0,当 ...
随机推荐
- 《精通并发与Netty》学习笔记(05 - Google Protobuf与Netty的结合)
protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等.其特点是不限语言.不限平台.扩展性强 Netty也提供了对Protobuf的天然支持,我们今天 ...
- docker部署jar、war包方法
一.将war包放入容器 1.# docker imagesREPOSITORY TAG IMAGE ID ...
- shell-常用命令,重定向和文件包含
shell的知识点并不多,这里简单介绍一下常用的一些东西 常用命令 echo 显示普通字符串 echo "test" 显示转义字符 echo "\"test\& ...
- 使用Docker Maven 插件进行镜像的创建以及上传至私服
1.在进行服务容器化部署的时候,需要将服务以及其运行的环境整个打包做成一个镜像,打包的过程有两种办法,第一种是首选通过maven打成jar包,然后再编写dockerfile,执行docker buil ...
- 【转帖】CentOS 7 修改时区
CentOS 7 修改时区 https://www.cnblogs.com/yaohong/p/7269878.html timedatectl 以及 time 分类: 操作系统-CentOS u ...
- 小记--------sparksql和DataFrame的小小案例java、scala版本
sparksql是spark中的一个模块,主要用于进行结构化数据的处理,他提供的最核心的编程抽象,就是DataFrame.同时,sparksql还可以作为分布式的sql查询引擎. 最最重要的功能就是从 ...
- idea配置glassFish
FIile ---> settings ---> 查找Application Server .. 点击加号,, 点击glassFish Server.. 找到glassFish存放路径 点 ...
- PAT B1012.数字分类
全部AC #include <cstdio> int valid[5] = {0}; int count[5] = {0}; int p1(int i) { printf("%d ...
- Yii2.0 queue
https://www.yiichina.com/tutorial/1635 https://my.oschina.net/gcdong/blog/3031113 https://www.yii-ch ...
- Git 学习笔记之(三)将本地工程导入到GitHub 仓库中
一:操作步骤第一步:建立git仓库 cd到你的本地项目根目录下,执行git命令,此命令会在当前目录下创建一个.git文件夹. git init 第二步:将项目的所有文件添加到仓库中 git add . ...