参考:中文维基

  • 二进制
  • 位操作(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+0=0,0+1=1,1+0=1,1+1=10
  • 减法:0-0=0,1-0=1,1-1=0,10-1=1
  • 乘法:0×0=0,0×1=0,1×0=0,1×1=1
  • 除法:0÷1=0,1÷1=1

计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。

计算的效率:位操作(位运算)

因为计算机的数据存储只有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是小数部分。分别使用不同的计算方式:

  • 整数部分:
    1. 进行带余除法运算。得到一个整数和一个余数。
    2. 对得到的整数继续进行第一步操作。直到步骤N得到商数为0。(商数:除法运算的结果。一般是指整数部分)
    3. 把上面多次带余除法运算得到的余数按照步骤从后往前排列组合。方法:(N代表第N步骤的余数):N组合N-1组合..1。组合得到就是二进制的整数数字部分。本例得到111011。
  • 小数部分:
    1. 对小数部分乘以2,得结果x,取x的整数部分。
    2. 对结果x乘以2,取其整数部分。如此反复,直到乘法得到的数字的小数部分全部为0为止。
    3. 读取所有乘法计算后得到的数字的整数部分,从第一步到最后一步组合。得到二进制的小数部分。本例是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 × 12 = 0)
1 × 2−2 (1 × 14 = 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-Za-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)

表示方法

不同电脑系统编程语言对于16进制数值有不同的表示方式:

C语言、C++、ShellPythonJava语言及其他相近的语言使用字首“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模块;的更多相关文章

  1. asp.net AES加密跟PHP的一致,将加密的2进制byte[]转换为16进制byte[] 的字符串获得

    <?php class AESUtil { public static function encrypt($input, $key) { $size = mcrypt_get_block_siz ...

  2. Android选择/拍照 剪裁 base64/16进制/byte上传图片+PHP接收图片

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/65633129认为博文实用,请点赞,请评论,请关注.谢谢! ~ 老规矩,先上GIF动态图 ...

  3. WPF 16进制byte输入框

    在WPF中,针对byte类型的输入控件可以选用 XCEED 的免费库中的 Xceed.Wpf.Toolkit.ByteUpDown(可从nuget获取). 若要使该控件在界面上以16进制显示byte, ...

  4. C语言:将16进制字符串转化为int类型值

    将16进制字符串值转换为 int 整型值 此例中用 "1de" 作为测试字符串,实现代码如下: #include <stdio.h> #include <stdl ...

  5. c# 16进制byte转成int

    ]; Ratedata=System.BitConverter.GetBytes(FreResultTBoxValue); 上面这个 FreResultTBoxValue 变量是int,系统中自带in ...

  6. python2/3中 将base64数据写成图片,并将图片数据转为16进制数据的方法、bytes/string的区别

    1.python2将base64数据写成图片,并将数据转为16进制字符串的方法 import binascii img = u'R0lGODlhagAeAIcAAAAAAAAARAAAiAAAzABE ...

  7. python - 2 8 16进制/颜色/字符编码

    1.二进制 八进制 十六进制 二进制: bin() 0b10010八进制: oct() 0o10十进制: 1-100十六进制: hex() 0X53 BH 十进制转2, 8,16进制: >> ...

  8. Java 将字节数组转化为16进制的多种方案

    很多时候我们需要将字节数组转化为16进制字符串来保存,尤其在很多加密的场景中,例如保存密钥等.因为字节数组,除了写入文件或者以二进制的形式写入数据库以外,无法直接转为为字符串,因为字符串结尾有\0,当 ...

  9. 关于QT内部16进制、十进制、QByteArray,QString

    QT里面的数据转化成十六进制比较麻烦,其他的int或者byte等型都有专门的函数,而十六进制没有特定的函数去转化,这我在具体的项目中已经解决(参考网上大神)->小项目程序 QT里面虽然有什么QS ...

随机推荐

  1. 《Node.js开发指南》的少许坑儿~

    由于express升级到3.0,造成这本书看起来more and more蛋疼.记录少许坑儿,方便后来人. 一.node.js在windows下的安装 书中在两处介绍了两种方式,其实现在的node.j ...

  2. 【锋利的jQuery】中全局事件ajaxStart、ajaxStop不执行

    最近一直都在研究[锋利的jQuery],确实是一本好书,受益匪浅.但由于技术发展及版本更新等原因,里面还是有些坑需要踩的. 比如:第六章七节中提到的全局事件ajaxStart.ajaxStop照着案例 ...

  3. busybox编译

    sync.c:(.text.sync_main+0x7c): undefined reference to `syncfs'Coreutils—>sync选项去掉 nsenter.c:(.tex ...

  4. Asp.net MVC WebApi项目的自动接口文档及测试功能打开方法

    https://blog.csdn.net/foren_whb/article/details/78866133

  5. [Umbraco] 创建第一个页面

    如何创建一个页面,很简单. 进入settings,首先右键点击“Document Types”, 在出现的菜单点击"Create",在弹出的窗口中 Master Document ...

  6. CFileDialog类的详情

    CFileDialog类封装了Windows常用的文件对话框. 常用的文件对话框提供了一种简单的与Windows标准相一致的文件打开和文件存盘对话框功能. void CnotepadDlg::OnOp ...

  7. Java邻接表表示加权有向图,附dijkstra最短路径算法

    从A到B,有多条路线,要找出最短路线,应该用哪种数据结构来存储这些数据. 这不是显然的考查图论的相关知识了么, 1.图的两种表示方式: 邻接矩阵:二维数组搞定. 邻接表:Map<Vertext, ...

  8. 汉字转拼音工具类java

    package com.baihui.core.utils; import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge. ...

  9. FutureTask 源码解析

    FutureTask 源码解析 版权声明:本文为本作者原创文章,转载请注明出处.感谢 码梦为生| 刘锟洋 的投稿 站在使用者的角度,future是一个经常在多线程环境下使用的Runnable,使用它的 ...

  10. 应用nslookup命令查看A记录、MX记录、CNAME记录和NS记录

    https://blog.csdn.net/qq_38058202/article/details/80468688