精华内容
下载资源
问答
  • 二进制数据编码方式
    2021-05-22 16:35:35

    通过查看其他博客的内容,整理一篇关于二进制霍夫曼编码的笔记供大家参考和讨论,如果有错误,欢迎大家联系我批评指正。

    一、二进制霍夫曼的原理

    我们可以将二进制霍夫曼编码拆分理解:

    二进制即 0、1;

    二进制编码就是用0和1的组合来表示其他字符;

    霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的熵编码(权编码)算法,通常用于无损数据压缩。(详见维基百科:https://en.wikipedia.org/wiki/Huffman_coding#n-ary_Huffman_coding)

    二、编码方法:

    1.将信源中n个符号按概率分布的大小,以递减次序排列(降序排列);

    2.用0和1分别分配给概率最小的两个信源符号,并将这两个概率最小的信源符号合并为一个新符号,并用这两个概率最小的信源符号合并成一个新符号,从而得到只包含n-1个符号的新信源,称其为缩减信源;

    3.把缩减信源的符号仍按概率大小降序排列,再将最后两个概率最小的符号合并为一个新符号,并分别用0、1表示,这样又形成一个新的缩减信源;

    4.按2、3步骤继续进行直到缩减信源最后只剩下两个符号位置。再将最后两个新符号分别用0和1表示。最后这两个符号的概率之和为1,然后从最后一级缩减信源开始,依编码路径右后向前返回,就可以得到各信源符号所对应的码符号序列,即对应的码字。

    通过典型的两个例题来介绍。

    例题一:字符串“alibaba”的二进制霍夫曼编码有多少位?

    1.1计算符号的概率并进行降序排序。

    符号

    概率

    a

    3/7

    b

    2/7

    i

    1/7

    l

    1/7

    1.2构建二叉树

    1.3从根节点数,得到a、b、i、l 对应的码字。

    符号

    概率

    编码

    a

    3/7

    0

    b

    2/7

    11

    i

    1/7

    100

    l

    1/7

    101

    例题二:现有一段文言文,要通过二进制哈夫曼编码进行压缩。假设这段文言文只由4个汉字“之”“乎”“者”“也”组成,它们出现的次数分别为700、600、300、200。那么,“也”字的编码长度是?

    同理,按照例题一的三个步骤进行就可以得到:

    符号

    概率

    编码

    700

    0

    600

    11

    300

    101

    200

    100

    答:3位。

    这道“之乎者也”没有像例题一一样出现相同的概率,但是其实保证字符的码字具有唯一性就行了。

    例题三:字符串“ABCDADA”的二进制哈夫曼编码有多少位?

    符号

    概率

    编码

    A

    3/7

    0

    D

    2/7

    10

    C

    1/7

    111

    B

    1/7

    110

    所以字符串“ABCDADA”的二进制哈夫曼编码为(0110111100100),共13位。

    出现次数越多的字符,编码越短;出现次数越少的字符,编码越长。这样就能让编码后的文件大小能够最短。

    更多相关内容
  • 在Rust中使用二进制数据和POD结构的工具的集合。 是一种构建安全接口以将POD结构与字节片进行来回转换的方法。 以安全,稳定的方式公开未对齐的打包数据结构。 提供了pod帮助程序,以及用于处理二进制数据流的...
  • 计算机二进制编码

    千次阅读 2020-10-17 17:00:56
    二进制编码知识。


    从康拉德·楚泽在 Z-3 计算机中首先采用二进制计数以来,现代电子计算机都采用二进制编码。

    • 二进制是最基本的进位计数系统,只有 0 和 1,容易表达。
    • 二进制运算规则简单,可以通过逻辑和移位电路实现。

    二进制虽然表达简单,但其内容与数位却不方便识别。

    • 4 位二进制可以表示 1 位十六进制。
    • 有时会用十六进制数来替代二进制数,能够更方便识别二进制的内容与位数。
    • 必须注意:十六进制只是用于方便识别二进制数的内容与数位,计算机并不存在这些十六进制数。

    1. 整数的二进制编码

    针对数值信息(数学值)的编码,将数值本身值称作真值,将编码称为机器数。

    • 例如:将数字 8 编码为 1000,那么 8 称为真值,1000 称为机器数。
    • 计算机中定义了两种整数:无符号数和符号数。

    2. 无符号数编码

    无符号数,顾名思义是没有符号的数,编码时无需考虑符号位的编码。可以直接用真值的二进制形式作为机器数,即编码值。

    • 8 位二进制可以表达十进制中的 0 ~ 255,共 2 8 2^8 28 = 256 个数。
    • 无符号数进行计算时,如果运算结果超出取值范围,就会产生错误,这种情况称为溢出。
    • 例如:[200] + [100] = 11001000B + 01100100B = 00101100B = [44]
    • 计算结果应该为 300,超过了 8 位二进制数的取值范围 [0 ~ 255],从而得到错误的结果 44。
    • 无符号数编码的的加法/减法通过最高位的进位/借位来判断。

    3. 符号数编码

    符号数,编码时就要考虑符号编码了,不仅要表示真值的绝对值,还要表示真值的符号。
    针对符号数有四种编码方式:

    • 原码:最高位表示符号(正数用 0 表示,负数用 1 表示),其他位表示真值的绝对值。
    • 反码:正数的反码等价于原码,负数的反码就是将原码除符号位以外的其他绝对值部分按位取反。
    • 补码:正数的补码依旧等价于原码,负数的补码是将反码加1得到。
    • 移码:移码在补码的基础上增加了一个偏移量。

    3.1 原码

    早期计算机使用原码表示法,X 为真值,n 为二进制数的位数,原码定义如下:
    { [ X ] 原 = ∣ X ∣ , 0 ≤ X ≤ 2 n − 1 [ X ] 原 = 2 n − 1 + ∣ X ∣ , − 2 n − 1 ≤ X ≤ 0 \begin{cases} [X]_原=\mid X\mid,\quad\quad\quad\quad\quad\quad\quad 0\leq X \leq 2^{n-1} \\ [X]_原=2^{n-1}+\mid X \mid,\quad\quad-2^{n-1}\leq X \leq 0 \end{cases} {[X]=X,0X2n1[X]=2n1+X,2n1X0
    最高位表示符号(正数用 0 表示,负数用 1 表示),其他位表示真值的绝对值。

    • 例如 [1000 0100B],最高位符号位是 1,表示负数,绝对值部分[000 0100B] 表达 4,组合起来表达 -4。

    原码特点:

    • 乘除运算比较方便,单独处理符号与真值绝对值。
    • 加减运算比较复杂,首先处理符号,确定做加法还是减法,如果是减法,还需比较真值的大小,确定结果的符号。
    • 特殊数字 0 的原码有两个,判断是否为 0 需要分别判断 [+0] = [0000 0000B][-0] = 1000 0000B
    • 8 位二进制数可以表示 0000 0000B ~ 1111 1111B,即 -127 ~ +127,共 255 个数。

    3.2 反码

    一些老式计算机使用反码表示法,X 为真值,n 为二进制数的位数,反码定义如下:
    { [ X ] 反 = ∣ X ∣ , 0 ≤ X ≤ 2 n − 1 [ X ] 反 = 2 n − 1 − 1 − ∣ X ∣ , − 2 n − 1 ≤ X ≤ 0 \begin{cases} [X]_反=\mid X\mid,\quad\quad\quad\quad\quad\quad\quad\quad\quad 0\leq X \leq 2^{n-1} \\ [X]_反=2^{n-1}-1-\mid X \mid,\quad\quad-2^{n-1}\leq X \leq 0 \end{cases} {[X]=X,0X2n1[X]=2n11X,2n1X0
    正数的反码等价于原码, 负数的反码就是将原码除符号位以外的其他绝对值部分按位取反,故得名反码。

    • 例如:-3 的原码为[1000 0011B] ,它的反码为 [1111 1100B]

    反码特点:

    • 符号位一起参与加、减运算。
    • 加法进位需要送回到最低位再加(循环进位)。
    • 减法借位需要送回到最低位再减(循环借位)。
    • 减法可以转换为加法,简化了算数逻辑单元的设计。
    • 0 的反码也有两个,即 [0000 0000B][1000 0000B]
    • 8 位二进制数可以表示 0000 0000B ~ 1111 1111B,即 -127 ~ +127,共 255 个数。

    3.3 补码

    反码较好地解决了符号参与运算的问题,但循环进位/借位延长了计算时间,为了进一步简化,引入了补码。X 为真值,n 为二进制数的位数,补码的定义如下:
    { [ X ] 补 = ∣ X ∣ , 0 ≤ X ≤ 2 n − 1 [ X ] 补 = 2 n − 1 − ∣ X ∣ , − 2 n − 1 ≤ X ≤ 0 \begin{cases} [X]_补=\mid X\mid,\quad\quad\quad\quad\quad\quad\quad 0\leq X \leq 2^{n-1} \\ [X]_补=2^{n-1}-\mid X \mid,\quad\quad-2^{n-1}\leq X \leq 0 \end{cases} {[X]=X,0X2n1[X]=2n1X,2n1X0
    正数的补码依旧等价于原码,负数的补码是将反码加1。

    • 例如:-3 的原码是 [1000 0011B],反码为 [1111 1100B],补码为[1111 1101B]


      补码的特点:
    • 与反码一样,补码的符号位参与加/减运算,但回避了循环进位/借位。
    • 与反码一样,补码的减法运算可转化为加法运算。
    • 0的补码只有一种,即 ⌈ 00000000 B ⌋ \lceil00000000B\rfloor 00000000B,所以补码可以表示 -128~+127,其中 ⌈ 10000000 B ⌋ \lceil10000000B\rfloor 10000000B不再表示 0,而是表示 -128

    补码判断溢出使用双高异或判别法,如果最高位进位/借位与此高位进位/借位不同,则表示溢出。

    • 例如 120 + 16 时,
      0 1 1 1 1 0 0 0 B ( + 120 ) 补 + 0 0 0 1 0 0 0 0 B ( + 16 ) 补 = 1 0 0 0 1 0 0 0 B ( − 120 ) 补 \begin{array}{ccccccccc} &0&1&1&1&1&0&0&0B&(+120)_补\\ +&0&0&0&1&0&0&0&0B&(+16)_补\\ \hline =&1&0&0&0&1&0&0&0B&(-120)_补 \end{array} +=0011001001101010000000B0B0B(+120)(+16)(120)
    • 次高位产生进位,为 1 ,最高位没有产生进位,为 0, 1 ⨁ 0 = 1 1\bigoplus0=1 10=1,说明溢出。

    3.4 移码

    移码在补码的基础上增加了一个偏移量,X 为真值,n 为二进制数的位数,补码的定义如下:
    [ X ] 移 = 2 n − 1 + [ X ] 补 − 2 n − 1 ≤ X ≤ n n − 1 [X]_移=2^{n-1}+[X]_补\quad\quad -2^{n-1}\leq X \leq n^{n-1} [X]=2n1+[X]2n1Xnn1
    以 8 位二进制为例,则:.
    0 0 0 0 1 0 0 1 B ( [ + 9 ] 补 ) + 1 0 0 0 0 0 0 0 B ( 2 8 − 1 ) = 1 0 0 0 1 0 0 1 B ( [ + 9 ] 移 ) \begin{array}{cc} &0&0&0&0&1&0&0&1B&([+9]_补)\\\\ +&1&0&0&0&0&0&0&0B&(2^{8-1})\\\\ \hline\\ =&1&0&0&0&1&0&0&1B&([+9]_移) \end{array} +=0110000000001010000001B0B1B([+9])(281)([+9])
    1 0 0 0 1 0 0 1 B ( [ − 9 ] 原 ) 1 1 1 1 0 1 1 0 B ( [ − 9 ] 反 ) 1 1 1 1 0 1 1 1 B ( [ − 9 ] 补 ) + 1 0 0 0 0 0 0 0 B ( 2 8 − 1 ) = 0 1 1 1 0 1 1 1 B ( [ − 9 ] 移 ) \begin{array}{cc} &1&0&0&0&1&0&0&1B&([-9]_原) \\ &1&1&1&1&0&1&1&0B&([-9]_反) \\\\ &1&1&1&1&0&1&1&1B&([-9]_补)\\ +&1&0&0&0&0&0&0&0B&(2^{8-1})\\ \hline =&0&1&1&1&0&1&1&1B&([-9]_移) \end{array} +=111100110101101011011000001101011011B0B1B0B1B([9])([9])([9])(281)([9])


    4. 总结

    • 无符号数的编码为其二进制的表达形式。
    • 符号数的编码分为原码、反码、补码和移码。
      • 原码:最高位为符号位,取1表示负数,取0表示正数,其他位为真值的绝对值。
      • 反码:正数的反码就是原码,负数的反码为原码的符号位以外的其他位全部按位取反。
      • 补码:正数的补码就是原码,负数的补码为反码加1。
      • 移码:补码的基础上添加一个偏移量。
    • 8 位二进制的原码、反码、补码部分表:
    真值原码反码补码
    -128^^1000 0000
    -1271111 11111000 00001000 0001
    -1261111 11101000 00011000 0010
    -31000 00111111 11001111 1101
    -21000 00101111 11011111 1110
    -11000 00011111 11101111 1111
    -01000 00001111 11110000 0000
    +00000 00000000 00000000 0000
    +10000 00010000 00010000 0001
    +20000 00100000 00100000 0010
    +30000 00110000 00110000 0011
    1270111 11110111 11110111 1111
    展开全文
  • 计算机组成原理--二进制编码

    千次阅读 2021-07-16 00:58:42
    算是读书笔记吧二进制编码二进制和我们平时用的十进制,其实并没有什么本质区别,只是平时我们是“逢十进一”,这里变成了“逢二进一”而已。每一位,相比于十进制下的 0~9 这十个数字,我们只能用 0 和 1 这两个...

    6b5479e6d036

    算是读书笔记吧

    二进制编码

    二进制和我们平时用的十进制,其实并没有什么本质区别,只是平时我们是“逢十进一”,这里变成了“逢二进一”而已。每一位,相比于十进制下的 0~9 这十个数字,我们只能用 0 和 1 这两个数字。

    二进制转十进制

    从右到左的第 N 位,乘上一个 2 的 N 次方

    0011 =>> 0×2³+0×2²+1×2¹+1×2⁰ = 3

    十进制转二进制

    用2做短除法

    6b5479e6d036

    因此13这个十进制数,对应的二进制数,就是 1101。

    原码表示法

    一个二进制数最左侧的一位,当成是对应的正负号,比如 0 为正数,1 为负数,这样来进行标记。

    0011 表示 +3、1011表示 -3

    但是对于0:1000 代表 0, 0000 也代表 0。

    补码表示法

    一个二进制数最左侧的一位,表示-1ⁿ

    1011 换算成十进制为:−1×2³+0×2²+1×2¹+1×2⁰=−5

    0000 表示 0,1000 在这样的情况下表示 -8。

    字符编码

    ASCII 码

    ASCII 码就好比一个字典,用 8 位二进制中的 128 个不同的数,映射到 128 个不同的字符里。

    比如,小写字母 a 在 ASCII 里面,就是第 97 个,也就是二进制的 0110 0001,对应的十六进制表示就是 61。而大写字母 A,就是第 65 个,也就是二进制的 0100 0001,对应的十六进制表示就是 41。

    在 ASCII 码里面,0-9每一个数字都对应这一个8位编码。所以很多时候我们在存储数据的时候,要采用二进制序列化这样的方式,而不是直接用CSV 或者 JSON进行存储。

    字符集(Charset)

    字符集,表示的可以是字符的一个集合

    我们日常说的 Unicode,其实就是一个字符集,包含了 150 种语言的 14 万个不同的字符。

    随着计算机的普及,越来越多的语言加入了Unicode。

    现在,他用32位,4个字节表示一个字符。

    字符编码(Character Encoding)

    类似一种传输协议,对Unicode编码后的编号进行压缩。

    Unicode本身的字符集是32位的,那么每个字符都用4个字节传输,对欧美而言,一下就要用原来ASCII码时代四倍的资源传输或者保存一样的文档。于是,出现了uft-8,utf-16,utf-32这些编码方案。

    把字符的代码通过这个编码方式映射成传输时的编码,在使用Unicode字符集保持通用性的同时节约流量和硬盘空间。

    UTF-8编码

    UFT-8编码可以保证最大限度的节约空间

    相对于Unicode这种大家固定的UTF-8的编码称之为变长码。其大受欢迎的主要原因就是对欧美而言,在保留Unicode通用性的情况下避免了流量和空间的浪费。

    用UTF-8在接收时,接到一个编码如果是合法的8位编码,就可以直接把它判定为字符,这就给了Unicode字符集在表示英语时和ASCII一样的效率。如果是不合法的,那继续读一个字节,读的两个字节16位如果是合法的,判别为一个字符,再不行继续读下去。

    为什么UTF-8成为主流

    计算机世界绝大部分传输的都是英文以及数字,编码之后UTF-16要两倍于UTF-8的空间

    为什么计算机不直接使用UTF-8进行编码

    UTF-8虽然更加节省空间,但是解析起来相对定长编码更加麻烦。

    不从头扫描一遍,你不知道第几个字符在哪个位置上,这在处理的时候非常浪费时间。

    现在很多语言/程序的处理办法,是使用源于原始UTF-16的一个定长编码,只处理字符码在16位以内的字符,不支持超过16位的罕见字。这种16位定长的编码方式被称为UCS-2。

    锟斤拷

    锟斤拷,是一串经常在搜索引擎页面和其他网站上看到的乱码字符。乱码源于GBK字符集和Unicode字符集之间的转换问题。

    `未知字符` ==(**Unicode**)==> `U+FFFD` ==(**UTF-8**)==>`\xef\xbf\xbd`

    `\xef\xbf\xbd\xef\xbf\xbd` ==(**GB2312**)==> `锟斤拷`

    GBK

    是汉字专用的字符编码方式

    GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:

    GBK、GB2312--Unicode--UTF8

    UTF8--Unicode--GBK、GB2312

    烫烫烫

    如果你用了 Visual Studio 的调试器,默认使用 MBCS 字符集。“烫”在里面是由 0xCCCC 来表示的,而 0xCC 又恰好是未初始化的内存的赋值

    定点数

    一种二进制来表示十进制的编码方式

    BCD 编码(Binary-Coded Decimal)

    我们把最右边的 2 个 0~9 的整数,当成小数部分;把左边 6 个 0~9 的整数,当成整数部分。这样,我们就可以用 32 个比特,来表示从 0 到 999999.99 这样 1 亿个实数了。

    它的运用非常广泛,最常用的是在超市、银行这样需要用小数记录金额的情况里。在超市里面,我们的小数最多也就到分。这样的表示方式,比较直观清楚,也满足了小数部分的计算。

    浮点数

    float类型

    IEEE 的标准

    它定义了两个基本的格式

    用 32 比特表示单精度的浮点数,也就是我们常常说的 float 或者 float32 类型。

    用 64 比特表示双精度的浮点数,也就是我们平时说的 double 或者 float64 类型。

    单精度float的表示

    单精度的 32 个比特可以分成三部分:

    6b5479e6d036

    符号位s

    1 个比特 -- 记做(−1)^s

    有效数位f

    23 个比特 -- 记做1.f

    指数位e

    8 个比特 -- 记做 2^(e)

    综合科学计数法,我们的浮点数就可以表示成下面这样:

    6b5479e6d036

    当然,有一些特殊的表示:

    6b5479e6d036

    举个例子:

    6b5479e6d036

    计算一个浮点数

    1. 整数部分

    与十进制相同。除以 2,然后看余数

    2. 小数部分

    乘以 2,然后看看是否超过 1。如果超过 1,我们就记下 1,并把结果减去 1,进一步循环操作。

    知道结果等于0

    比如9.1、整数位9换算成1001。

    而小数位0.1:

    6b5479e6d036

    结果是000110011…这里的“0011”会无限循环下去。所以,这也是为什么0.1无法被正确的表示为浮点数的原因。

    1001后拼接上000110011… 也就是 1001.000110011…

    进行位移之后为 1.001000110011… × 2^3

    什么样的数无法被精准的表示成浮点数

    二进制能精确地表示位数有限且分母是2^n的小数

    比如1/2、1/4、1/8

    他们在乘2的循环中,一定有一次能使结果等于1,从而推出循环。

    而且,需要在有限位数内完成循环。毕竟有效数位f只有23个比特。

    参考文献

    展开全文
  • 二进制数据图片 前言 最近公司那台终端电脑的粘贴功能坏了, 连接远程想从里面拿一个文件出来, 试了好多种方法不顶用, 远程终端开了一堆程序也不能随便重启远程终端, 最终是关了一大堆不必要的应用, 又重启了下...

    二进制数据图片

    前言

    最近公司那台终端电脑的粘贴功能坏了, 连接远程想从里面拿一个文件出来, 试了好多种方法不顶用, 远程终端开了一堆程序也不能随便重启远程终端, 最终是关了一大堆不必要的应用, 又重启了下rdpclip.exe解决了

    Windows服务器远程桌面不能复制粘贴的解决方法

    但是解决过程中, 突然想: 复制粘贴不能用, 但是可以正常显示远程的屏幕, 能不能通过截屏就能把文件给搞下来呢?
    于是在一波捣鼓之后, 就有了bit-data-map和本文章

    名称

    bit-data-map, bdmp, 点阵图, 像素点阵图, 文件点阵图, 数据像素点阵图.

    关于这种图片的名字, 我其实是想了好久的, 最开始是binary-picture, 之后是pixelPic, 之后考虑这种存储信息类似于点阵, 同时每一个点阵像素代表着一个bit或多个bit的数据, 因此决定使用map作为名称, 于是名称又变成了数据点阵图片binary-pixel-map, 后来名称又变成二进制数据图片binary-data-map, 现在变成了 bit-data-map, 简称bdmp.

    简介

    简单来说就是通过图片来保存数据的一种方式, 例如将文件中的数据存储到图片中, 同时能够将图片中的数据重新转换为文件.

    引入目的

    在某种情况下, 通过图片的形式传递数据信息.

    简单说一个示例, 例如当你打开远程桌面, 突然发现粘贴板坏了, 此时你需要复制里面的文件到你本地的电脑, 然后就可以将远程桌面的文件转换为图片, 之后通过截屏方式截取屏幕到你的电脑, 之后在你的电脑上重新识别为文件.

    二维码是一种通过图片来传递数据信息的方式, 但是二维码传递的信息量太小, 有时我们可能需要通过图片传递大量信息, 例如通过截屏来传递信息.

    像素图片引入

    一般情况下, 文件以二进制形式保存, 除此之外, 文件还有其它保存方式. 例如将文件转换为Base64编码保存为文本形式, 那么将文件转换为图片点阵方式保存为像素文件也自然是可以的.

    点阵系统中, 一个位置, 我们使用白色代表有这个点, 黑色代表没有这个点, 有这个点可以视为1, 没这个点作为0, 那么一个点就可以对应一个bit.

    但是我们使用的图片不是黑白图片, 图片颜色多种多样.

    假如一个像素有2种颜色, 则一个像素可以代表1个bit
    假如一个像素有4种颜色, 则一个像素可以代表2个bit
    假如一个像素有16种颜色, 则一个像素可以代表4个bit
    假如一个像素有256种颜色, 则一个像素可以代表8个bit

    假如一个像素有2^n种颜色, 则一个像素可以代表n个bit

    我们使用png图片来表示这个点阵, 一个像素表示点阵中的一个点, 一般来讲一个像素可以使用 256 * 256 * 256种颜色.

    假如png图片中, 每个像素有256种颜色, 那么一个像素就可以代表一个字符(8个bit), 假如屏幕分辨率不大, 只有1366 * 768, 那么一张图片便能够存储1366 * 768 = 1,049,088bit数据(差不多是1M数据, 1M数据是1024 * 1024 = 1,048,576bit).

    而对于全高清屏(1920*1080)来说, 假如每个像素能够代表1个字节(1Byte), 那么整个屏幕就是(1920*1080=2073600)差不多有2M(1024*1024*2=2097152)数据, 假如每个像素能够代表2个字节(2Byte), 那么一个截屏就能获取将近4M数据, 如果再配合滚动截屏软件, 那么就可以通过屏幕传输更大的数据.

    而如果是远程桌面配合本地软件滚动截屏的话, 那么就能够存储更多.

    像素图片设计

    图片格式

    像素图片格式选择png图片格式, 因为.png是不会失真, 而 .jpg 图片格式会失真.

    像素内容设计

    将一个文件转换为像素图片后, 还能够再从像素图片转换为文件, 那么至少需要将文件的文件名等文件信息存入像素图片中.

    图片中的像素颜色在截屏时可能会出现失真, 例如像素的颜色在经过截屏之后变成了宁外一种颜色(具体会不会, 我没有具体研究过, 只不过我这么认为而已), 因此在像素图片头部将代表颜色的像素依次写入图片可以有效地防止图片的颜色改变

    假如点阵有4种颜色, 白, 黑, 黄, 绿, 分别代表0, 1, 2, 3. 那么就在头部将这4中颜色写入图片, 读取图片的时候, 先读取这写颜色, 之后所有的像素都按照这几种颜色进行解析成二进制.

    像素图片有效区域

    一个像素图片可以通过矩形截屏, 截屏之后的图片也能够转换为文件, 那么如何确定像素图片的有效内容呢?

    类似于二维码有黑白黑的正方形定位区, 可以用来定位和识别二维码, 但是像素图片不需要那么复杂, 有效内容外包裹一圈黑白相间的点阵即可.

    像素图片生成流程

    1. 首先读取要制作为像素图片的文件, 根据文件的名称, 大小, 以及传入的参数计算并确定出像素图片大小, 像素图片的颜色类型, 每个点的宽度, 图片内容边缘宽度, 定位区等信息.
    2. 根据上一步计算的信息生成.png图片, 添加背景色为灰色, 之后在内容定位区外边缘绘制出一圈黑白相间的点(左上角的点为黑色起始点, 之后向下, 向右两个不同的方向扩展到右下角).
    3. 写入像素图片标记, 像素颜色数量, 像素颜色, 一行像素数量, 像素图片头长度.
    4. 将文件名称, 文件日期, 文件MD5码等信息封装后写入像素头.
    5. 写入像素内容.
    6. 生成像素图片.

    像素图片解析流程

    1. 读取图片
    2. 找到像素信息有效位置
    3. 获取像素信息数据
    4. 解析像素信息数据
    5. 将Md5值和解析后的像素信息数据做对比
    6. 转储为文件.

    demo 示例

    例如 二进制数据图片 这几个文字的表达方式.

    1. 二进制数据图片

      每个像素代表1个bit数据.
      使用黑色和白色做边框, 使用红色和蓝色作为二进制的 0, 1, 生成的图片

    2. 四进制数据图片

      每个像素代表2个bit数据.
      灰色, 红色, 绿色, 蓝色 分别代表 四进制的 0, 1, 2, 3.
      四进制数据图片

    3. 16进制数据图片

      每个点代表4bit数据.
      16进制数据图片

    4. 256进制数据图片

      每个点代表8bit数据(1个字节).
      256进制数据图片

    5. 一个84Kb的bit数据图片, 以及他的二进制像素图片,

      每个点代表8bit数据
      bdmp-core.zip 文件大小84.1KB, 其生成的bit-data-map图片大小为100kb.
      在这里插入图片描述
      在这里插入图片描述

    git

    相关源码我已放到了github和gitee上管理, 上面有最新的代码, 以及一些开发中的功能, 欢迎大家下载查看

    github: https://github.com/cosycode/bit-data-map
    gitee: https://gitee.com/cosycode/bit-data-map`

    同时我也将代码打包成jar, 发布到 maven 仓库, 欢迎大家使用

    repo

    1. Apache Maven

      <dependency>
      <groupId>com.github.cosycode</groupId>
      <artifactId>bit-data-map</artifactId>
      <version>1.0</version>
      </dependency>
      
    2. gradle

      implementation 'com.github.cosycode:bit-data-map:1.0'
      

    使用方式

    1. 在项目中导入jar

    2. 将文件转换为图片示例

      
       /**
        * 生成二级制数据像素图片方式0
        *
        * @throws IOException 读取文件异常
        */
       @Test
       public void geneBdmp0() throws IOException {
           // 待转换的文件
           final String SOURCE_PATH = "D:\\Users\\CPF\\Desktop\\轻音乐-兰花草.mp3";
           // 转换后的文件存放位置
           final String bdmpFilePath = SOURCE_PATH + ".png";
      
           BdmpHandle.convertFileToBdmp(SOURCE_PATH, bdmpFilePath, 800, 2, 20, (byte) 8);
       }
      
       /**
        * 生成二级制数据像素图片方式1
        *
        * @throws IOException 读取文件异常
        */
       @Test
       public void geneBdmp1() throws IOException {
           // 待转换的文件
           final String SOURCE_PATH = "D:\\Users\\CPF\\Desktop\\轻音乐-兰花草.mp3";
           // 转换后的文件存放位置
           final String bdmpFilePath = SOURCE_PATH + ".png";
      
           // 数据源
           final BdmpSource bdmpSource = BdmpSource.geneByFile(new File(SOURCE_PATH));
           // 二进制数据图片配置
           BdmpGeneConfig config = new BdmpGeneConfig();
           // 设置图片边缘为 20px
           config.setMargin(20);
           // 设置图片一行点阵数量为 800 个
           config.setRowPixelCnt(800);
           // 设置每个点阵宽度为1像素
           config.setPixelSideWidth(1);
           // 设置每个点阵高度为1像素
           config.setPixelSideHeight(1);
           // 设置 每个点阵表示 8 bit, 每个点阵有 2^8 = 256种颜色
           config.setMappingColor(BdmpUtils.getPxType(8));
           // 生成的bit-data-map的生成信息类
           final BdmpGeneInfo bdmpGeneInfo = new BdmpGeneInfo(config, bdmpSource);
           // 生成图片
           final BufferedImage image = PixelPngDrawer.geneRatePixelPng(bdmpGeneInfo);
           // 保存图片 png表示保存格式
           ImageIO.write(image, "png", new FileOutputStream(bdmpFilePath));
       }
      
      
    3. 将图片转换回文件示例

       @Test
       public void recBdmp() throws IOException {
           // 待转换的图片文件
           final String SOURCE_PATH = "D:\\Users\\CPF\\Desktop\\轻音乐-兰花草.mp3.png";
           // 转换后的文件存放文件夹
           final String recDirPath = "D:\\Users\\CPF\\Desktop\\";
           
           BdmpHandle.convertBdmpToFile(SOURCE_PATH, recDirPath);
       }
      
    4. 转换的文件信息以及转换后的图片信息
      在这里插入图片描述
      在这里插入图片描述

    有了这个,以后从远程终端取文件就不需要直接传输文件了

    展开全文
  • 浅谈计算机信息的二进制编码

    千次阅读 2021-07-16 00:57:36
    摘 要 数据是计算机处理的对象,从不同的处理角度来看,数据有不同的表现形态。从外部形式来看计算机颗处理数值、图、文字、声音、视频以及各种模拟信息量。从高级语言程员的角度来看,有数组、指针、结构、实数、...
  • 【转】HTTP传输二进制 数据编码解码

    千次阅读 2017-07-03 18:41:04
    【转】HTTP传输二进制初探 从第一次接触http协议的时候,不知是怎么回事,形成了这么一个错误的观点,认为http协议是个纯ASCII字符协议,也就是说在http流里是看不到二进制流的0x00值的。其实答案是:http协议...
  • 概述通过前三篇博客,我们能够了解在通过WebSocket发送数据之前,我们需要传递的数据是如何变成ArrayBuffer二进制数据的;在我们收到二进制数据之后,我们又如何将其变成了JavaScript中的常见数据类型。本文作为...
  • 二进制的三种编码:原码,反码,补码 以前不是很理解,最近有时间进行了补充学习,通过两篇渐进关系的文章让我清晰了很多: 第一篇: 一. 机器数和真值 在学习原码, 反码和补码之前, 需要先了解机器数和真值...
  • 使用记事本,输入 “11111”,以unicode 编码方式保存文件。发现除了1 的ASCII 编码0031 以外,在文件开始的部分多了 “FF FE ”,这个FF FE 就是文件头标志,表示这是一个以unicode 编码,小端方式 (little endian...
  • 二进制数据转字符

    2022-06-14 20:43:38
    二进制数据转字符
  • 二进制编码-详细讲解

    千次阅读 2021-07-28 07:48:17
    负数:原码就是原来的表示方法反码是除符号位(最高位)外取反补码=反码+1以前学习二进制编码时,老师讲了一堆堆的什么原码啊反码啊补码啊xxxx转换啊,还有负数的表示方式啊 总是记不零清,终于从网上找到了一种比较好...
  • Json二进制数据

    千次阅读 2021-03-15 01:51:35
    如果想要传输图片等二进制文件的话,是没办法直接传输。本文提供一种思路给大家参考,让大家可以在json传输二进制文件,如果大家有这个需求又不知怎么实现的话,也许本文能够帮到你。思想适用于所有语言,本文以java...
  • Python二进制数据处理

    万次阅读 多人点赞 2019-01-10 15:11:56
    目录前言str与bytesbase64模块struct模块...当然本篇文章不是去说编码的,而是主要讲讲二进制处理,python 3为我们提供了bytes,利用bytes可以一定程度上缓解编码出错的问题,因为bytes是字节序列,无所谓编码。下...
  • 从文件编码方式来看,文件可分为ASCII码文件和二进制码文件两种。 ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。例如,数5678的存储形式为: ASC码: 00110101 ...
  • 二进制编码

    2021-07-20 22:33:35
    我们都知道,一个程序是=数据结构+算法,如果对应到组成原理或者是硬件层面上来说,算法就是我们的各种计算机指令,而数据结构就是我们对应的二进制数据 字符串的表示,从编码到数字 其实不仅数字可以用字符串来表示...
  • Python 字符串数据二进制编码数据)格式转换及解析 最近在linux上部署python,希望可以用python来调用串口,同时可以实现数据的格式转换。 在python这个做格式化转换不熟悉,花了一点时间研究了一下:一般来说,...
  • JavaScript存储与操作二进制数据

    千次阅读 2022-01-24 11:21:17
    于是写这篇的目的就是为了加固对二进制数据的理解,以及JavaScript中如何操作二进制数据的。 ArrayBuffer 其他语言java,易所表示的是字节数组,字节集,而在js中则称二进制数组(都是用来表示二进制数据的),要...
  • 基于二进制编码的移动端应用数据解析算法,杨一帆,刘会永,随着移动互联网的迅速发展,移动应用已经广泛影响到人们的生活方式。由于对移动应用需求量的日益增多,用户对移动应用的要求也日
  • 详解JavaScript操作文件和二进制数据

    千次阅读 2020-12-29 06:02:54
    在很长的一段时间内 JavaScript 是不能操作二进制数据的。同样的为了安全性,直接操作文件也是不被支持的。...charCodeAt()方法,支持一个个字节地从文字编码转成二进制数据,还有一种办法是将二进制数据转成 Base6...
  • 二进制与字符编码

    2021-11-14 18:07:51
    二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。 二:有两个位数,分别是0和1 进:这两个位数循环和重复使用 制:它是一种应用规范,目前主要直接源于...
  • 第一步,在 axios 请求中加入参数,表示接收的数据二进制文件流 responseType: 'blob' 第二步,在拿到数据流之后,把流转为指定文件格式并创建a标签,模拟点击下载,实现文件下载功能 let blob = res.data let reader =...
  • 在WebSocket中使用protobufjs对二进制数据进行解码编码 现在的项目中有一个需求是通过WebSocket连接后端进行视频回放功能的实现 由于是HTTPS网页,WebSocket中使用wss进行连接,在连接时也时有一些坑的, wss连接...
  • 二进制和量化编码

    千次阅读 2021-04-18 00:11:20
    小数 10 进制转二进制: 如 0.8, 转为 2 进制要: 0.8×2=1.6→10.6×2=1.2→10.2×2=0.4→00.4×2=0.8→00.8×2=1.6→1⋮×2=⋮→⋮ \begin{aligned} 0.8 \times 2=1.6\to1 \\ 0.6\times2=1.2\to1\\ 0.2\times2=0.4...
  • } 赫夫曼编码 1、赫夫曼编码也翻译为 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式, 属于一种程序算法 2、赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。 3、赫夫曼编码广泛地用于数据文件...
  • 二进制编码数字

    千次阅读 2021-07-31 05:31:49
    同义词计算机编码一般指二进制编码数字二进制编码数字[1],即计算机编码,指电脑内部代表字母或数字的方式。中文名二进制编码数字外文名Computer number format别名计算机编码领域二进制编码数字位元、字节、字组位...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 298,295
精华内容 119,318
热门标签
关键字:

二进制数据编码方式