百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

计算机储存数字和字符的方法你了解多少?

ztj100 2024-11-24 01:32 25 浏览 0 评论

作者:薛8

来源:https://ddnd.cn/2019/02/16/byte-hex-ascii/

前言

最近在学习中涉及到计算机储存、传输数字和字符等操作,由于对字节、2进制、10进制、16进制、ASCII码的概念以及它们之间的关系和转换理解的不够透彻,导致在通讯、MD5消息摘要算法等时候出现问题,是因为数据转成计算机认识的01的这个环节出现问题。由于这个问题并不是那么容易发现,所以我也算是花了挺多时间才解决了这个问题,记录下解决过程,顺便也当复习一下计算机组成原理。

ASCII码

在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。
ASCII 码一共规定了128个字符(0000 0000-0111 1111)的编码,比如空格SPACE是32(二进制0010 0000),大写的字母A是65(二进制0100 0001 )。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位(低7位),最前面的一位(高1位)统一规定为0(不要和数字的符号位搞混)。
当然除了ASCII码,还有UTF-8、GBK等。

字节

字节(Byte)普通计算机系统能读取和定位到最小信息单位,即我们通过计算机储存和传输数据的时候都是先把数据转成字节。
字节即Byte,一个字节代表8个比特(Bit),字节通常缩写为B,比特通常缩写为b。字节的大小是8Bit,即字节的范围是0000 0000 - 1111 1111,对于无符号型,它表示的十进制范围是[0,255],对于有符号型,高一位表示符号位,它表示的十进制范围是[-128,127]。

计算机若何储存数据

计算机只认识0和1(因为计算机只有高低电平两个状态),数据要想通过计算机储存或者传输,首先是要把数据转成计算机能认识的格式即01数据。
我们举个例子,以储存十进制数字28和-28为例,首先将十进制数转成二进制。

需要注意的是: 数字在计算机中储存的是补码,而字符是在计算机中储存的是字符对应的编码(不要和数字的补码搞混)。

数字

储存十进制数字28和-28为例,首先将十进制数转成二进制,高1位为0代表正数,为1代表负数

28(10) = 0001 1100(2)(原码)

-28(10) = 1001 1100(2)(原码)

然后计算机将二进制数字进行补码运算,运算结果如下

28(10) = 0001 1100(2)(原码) = 0001 1100(2)(补码)

-28(10) = 1001 1100(2)(原码) = 1110 0100(2)(补码)

然后计算机保存的就是补码,当要取出数据的时候,就将补码逆运算一下,即可求出原码,再将原码转换一下就可以得到真实的数据了。
下面以Java语言演示这个过程,首先我们要清楚Java的byte、short、int、long都是有符号的(signed)

运行输出:

28储存到计算机后为:11100

-28储存到计算机后为:11111111111111111111111111100100

取出储存的28 以无符号表示:28

取出储存的-28 以无符号表示:4294967268

我们验证一下结果,验证了计算机确实是以补码的方式储存数字。这里有个小问题,就是我们知道int型有4个字节即32个比特,但是28却输出了111005个比特而已,是因为toBinaryString()方法把11100前面的0给忽略了。
取出的时候,我们以无符号的标准去处理,导致取出存入的-28结果是4294967268和我们存入的不一样,这是因为-28是负数,负数的补码和原码不一样,而用无符号处理的话就是直接将11111111111111111111111111100100转成结果了。而为什么28用有无符号处理结果都一样是因为正数的原码和补码一样,这样验证了Java的数据类型都是有符号的。

至于计算机为什么用补码来储存数字,而不是原码,原因是:
拿单字节整数来说,无符号型,其表示范围是[0,255],总共表示了256个数据。有符号型,其表示范围是[-128,127]。
先看无符号,原码和补码都一样,0表示为0000 0000,255表示为1111 1111,刚好满足了要求,可以表示256个数据。
再看有符号的,若是用原码表示,0表示为0000 000。因为咱们有符号,所以应该也有个负0(虽然它还是0)1000 0000。这样的话那就有2个0,也就是只能表示255个数据,不能够满足我们的要求。而用补码则很好的解决了这个问题。

字符

在计算机中,对非数值的字符进行处理时,要对字符进行数字化,即用二进制编码来表示字符。其中西文字符最常用到的编码方案有ASCII编码和EBCDIC编码。对于汉字,我国也制定的相应的编码方案,比如 GBK,GB2312等。
比如字符a的ASCII码十进制值为97,在计算机中用二进制表示就是 01100001。下面同样用Java来演示计算机是如何储存字符的。

  1. 采用UTF-8和GBK两种编码储存汉字


我们调试看看,发现GBK编码采用2个字节储存,储存的数据分别是10进制的-42和-48对应的二进制分别是11010110和11010000(补码),即汉字中对应的二进制为1101011011010000,即16进制的D6D0,查看GBK对照表,发现16进制编码D6D0对应的汉字确实是中

而UTF-8编码采用3个字节储存,同理将对应的二进制111001001011100010101101转成16进制,为E4B8AD,通过UTF-8编码查询,发现汉字中对应的16进制编码确实是E4B8AD

  1. 储存字符


调试看看,字符串EF有E和F两个字符,它们对应的十进制ASCII码分别是69和70

我们发现Java的getBytes()方法是将字符串的每一个字符都储存到一个字节的,如果我们想把EF储存在一个字节里面,即EF是一个整体的,一个字节,不能拆分,那我们可以把EF放在一个字节里面(byte)(0xEF),声明它是一个字节,不是字符,不用再将它转成字符对应的编码。
下面说说我在进行MD5消息摘要算法时候遇到的坑,我要对QQ号对应的Hex进行MD5算法散列,这里我举例QQ号的10进制为12345678,对应的16进制为00BC614E(因为QQ号固定长度4个字节,所以前面补了2个0),一开始我是以下面的方式进行MD5算法的


调试可以看到上面的代码其实是将字符串00BC614E转成了8个字节,然后再对这8个字节进行散列,这也是基于字符串进行的MD5散列,和通过网上一些网站散列得到的值是一样的

但是这个哈希值和预想的结果不一致,后来才知道预想的结果是基于字节进行的MD5散列,也就是00BC614E应该分成4个字节(00、BC、61、4E)而不是8个字节(0、0、B、C、6、1、4、E),然后通过修改代码


使用(byte)声明是一个字节,不是字符,不用再将它转成字符对应的编码。00、BC、61、4E分别是一个字节,当然因为字节为8个比特,能表示256个数字,因为Java的数据类型是有符号的,所以8个比特能表示的10进制范围是[-128,127],所以(byte)(x) x不能小于-128和不能大于127,否则会溢出,溢出的部分数据会丢失。

相关推荐

30天学会Python编程:16. Python常用标准库使用教程

16.1collections模块16.1.1高级数据结构16.1.2示例...

强烈推荐!Python 这个宝藏库 re 正则匹配

Python的re模块(RegularExpression正则表达式)提供各种正则表达式的匹配操作。...

Python爬虫中正则表达式的用法,只讲如何应用,不讲原理

Python爬虫:正则的用法(非原理)。大家好,这节课给大家讲正则的实际用法,不讲原理,通俗易懂的讲如何用正则抓取内容。·导入re库,这里是需要从html这段字符串中提取出中间的那几个文字。实例一个对...

Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)

实现功能:Python数据分析实战-利用正则表达式提取文本中的URL网址和邮箱...

python爬虫教程之爬取当当网 Top 500 本五星好评书籍

我们使用requests和re来写一个爬虫作为一个爱看书的你(说的跟真的似的)怎么能发现好书呢?所以我们爬取当当网的前500本好五星评书籍怎么样?ok接下来就是学习python的正确姿...

深入理解re模块:Python中的正则表达式神器解析

在Python中,"re"是一个强大的模块,用于处理正则表达式(regularexpressions)。正则表达式是一种强大的文本模式匹配工具,用于在字符串中查找、替换或提取特定模式...

如何使用正则表达式和 Python 匹配不以模式开头的字符串

需要在Python中使用正则表达式来匹配不以给定模式开头的字符串吗?如果是这样,你可以使用下面的语法来查找所有的字符串,除了那些不以https开始的字符串。r"^(?!https).*&...

先Mark后用!8分钟读懂 Python 性能优化

从本文总结了Python开发时,遇到的性能优化问题的定位和解决。概述:性能优化的原则——优化需要优化的部分。性能优化的一般步骤:首先,让你的程序跑起来结果一切正常。然后,运行这个结果正常的代码,看看它...

Python“三步”即可爬取,毋庸置疑

声明:本实例仅供学习,切忌遵守robots协议,请不要使用多线程等方式频繁访问网站。#第一步导入模块importreimportrequests#第二步获取你想爬取的网页地址,发送请求,获取网页内...

简单学Python——re库(正则表达式)2(split、findall、和sub)

1、split():分割字符串,返回列表语法:re.split('分隔符','目标字符串')例如:importrere.split(',','...

Lavazza拉瓦萨再度牵手上海大师赛

阅读此文前,麻烦您点击一下“关注”,方便您进行讨论和分享。Lavazza拉瓦萨再度牵手上海大师赛标题:2024上海大师赛:网球与咖啡的浪漫邂逅在2024年的上海劳力士大师赛上,拉瓦萨咖啡再次成为官...

ArkUI-X构建Android平台AAR及使用

本教程主要讲述如何利用ArkUI-XSDK完成AndroidAAR开发,实现基于ArkTS的声明式开发范式在android平台显示。包括:1.跨平台Library工程开发介绍...

Deepseek写歌详细教程(怎样用deepseek写歌功能)

以下为结合DeepSeek及相关工具实现AI写歌的详细教程,涵盖作词、作曲、演唱全流程:一、核心流程三步法1.AI生成歌词-打开DeepSeek(网页/APP/API),使用结构化提示词生成歌词:...

“AI说唱解说影视”走红,“零基础入行”靠谱吗?本报记者实测

“手里翻找冻鱼,精心的布局;老漠却不言语,脸上带笑意……”《狂飙》剧情被写成歌词,再配上“科目三”背景音乐的演唱,这段1分钟30秒的视频受到了无数网友的点赞。最近一段时间随着AI技术的发展,说唱解说影...

AI音乐制作神器揭秘!3款工具让你秒变高手

在音乐创作的领域里,每个人都有一颗想要成为大师的心。但是面对复杂的乐理知识和繁复的制作过程,许多人的热情被一点点消磨。...

取消回复欢迎 发表评论: