20145233 《信息安全系统设计基础》第3周学习总结

20145233 《信息安全系统设计基础》第3周学习总结

教材学习内容总结

本次老师给的私人课程中,主要让我们仔细对待课后习题,其中老师说了很多重点题目。
其中大部分指导都是老师让大家看了课后题之后的思考,看来第二章是书上的内容足够全面。

第二章的前序

三种最重要的数字表示:

  • 无符号
  • 浮点数
  • 补码

两种计算方式:

  • 浮点运算
  • 整数运算

信息存储

计算机最小的可寻址的存储器单位——字节
一、十六进制表示法

  1. C表示法

以0x或0X开头的数字常量为十六进制
2. 进制转换

常用进制:二进制(B),十进制(D),八进制(O或者Q),十六进制(H)
转换为二进制-十六进制相互转换,二进制的四位数字对应十六进制的一位数字。
同理,二进制与八进制的转化是三位对应一位。
但是通常情况下,进制转换都以二进制为桥梁进行转换。
二、字
每台计算机都有一个字长,指明整数和指针数据的标称大小,因为虚拟地址是以这样的一个字来编码的,所以字长决定的最重要的系统参数就是虚拟地址空间的最大大小。
当今大多数计算机已经是64位,书上的32位已经是几年前的数据了。
对于一个字长为w位的机器来说,虚拟地址的范围是0~2^w-1。程序最多访问2的w次方个字节。
1.数据大小
在不同字长的计算机中,相同的数据类型所占用的字节数并不相同,32位和64位的区别参见教材26页表格。
使用C99特性时 gcc -std=c99 xxx.c 实验楼环境为64位,编译为32位机器码: gcc -m32 xxx.c
2.寻址和字节顺序

以0x01234567举列来说:

  • 大端法:
    最高有效位在前所以是: 01 23 45 67
  • 小端法:
    最低有效位在前所以是: 67 45 23 01
    3.强制类型转换
    用来允许一种数据类型引用一个对象,而这种数据类型与创建这个对象的定义的数据类型不同。大多数应用编程多不推荐这种编程技巧。

三、表示字符串和代码
C语言中字符串被编码为一个null字符结尾的字符数组。每个字符串都由某个标准编码来表示,最常见的是ASCII字符码。
在代码中,就是处理器完全一样,但是运行不同的操作系统,也会有不同的编码规则,因此二进制代码是不兼容的。二进制代码很少能在不同机器和操作系统组合之间移植。
四、位运算
1.布尔代数
常用运算符号:

与: &
或: |
非: ~
异或:^

2.位向量

  • 位向量:有固定长度为w、由0和1组成的串。
  • 位向量的应用——表示有限集合。

3.位级运算

  • 位运算:位向量按位进行逻辑运算,结果仍是位向量(区别于逻辑运算)
  • 位级运算的一个常见用法就是实现掩码运算,这里掩码是一个位模式,表示从一个字中选出的为的集合。
    4.C语言中的移位运算
    C语言标准并没有明确定义应该使用那种2类型的右移。对于无符号数据,右移必须是逻辑的。而对于有符号数据,算术的或者逻辑的右移都可以。
    c语言中的移位运算

左移<<
右移分为逻辑右移和算术右移。(其实左移也区分,但是算术左移和逻辑左移没有什么区别)

  • 逻辑右移:
    在左端补k个0,多用于无符号数移位运算

  • 算术右移:
    在左端补k个最高有效位的值,多用于有符号数移位运算。

  • 优先级
    移位运算的优先级比算术运算(比如+、-)要低

整数表示

一、整型数据类型
整型数据类型——表示有限范围的整数,每种类型都能用关键字来指定大小,还可以指定是非负数(unsigned)还是负数(默认)。这些不同大小的分配的字数会根据机器的字长和编译器有所不同。

  • 关于取值范围
    32位机器和64位机器对于同一数据类型的典型取值范围是有所不同的。
    典型取值范围中,取值范围不对称——负数的范围比整数的范围大1。
    c语言标准定义的每种数据类型必须能够表示的最小的取值范围中,正数和负数的取值范围是对称的。
    二、无符号数的编码
    无符号数的二进制表示有一个很重要的属性,就是每个介于0~2的w次方-1之间的数都有唯一一个w位的值编码。
    例如:十进制值11作为无符号数,只有一个4位的表示,即1101这个属性用数学语言来描述就是函数B2Uw是一个双射。
    C语言支持所有的整型数据类型的有符号和无符号运算。

整数运算

一、无符号运算
无符号运算本质上就是模运算,mod 2的w次幂。
1.加法
涉及到的相关知识有:交换群(阿贝尔群),单位元,加法逆元等等。计算起来很简单。
2.乘法
两个w位的无符号数相乘,实际上是截取了低w位,但是等价于mod 2的w次幂。
二、补码运算
1.补码用法
对于补码加法,我们必须确定结果太大或者太小时,应该做些什么。
两个数的w位补码之和与无符号数之和有完全相同的位级表示。大部分计算机使用同样的机器指令来执行无符号或者有符号加法。
老师给我的上一篇的评价是少摘抄,我本来觉得这是一种适合我的记忆手段,但是杂乱的知识点很碎,所以我决定听取老师的意见,放弃记录要点,多动手实践,后面的知识要点我就在练习中试验了。

教材重点

p20: 三种数字:无符号数、有符号数(2进制补码)、浮点数,信息安全系同学从逆向角度考虑为什么会产生漏洞
因为算数运算的微妙细节引发漏洞,增加精度弥补细节可以减少漏洞。

p22: 进制转换,注意拿二进制作中间结果就好转了

p25: gcc -m32 可以在64位机上(比如实验楼的环境)生成32位的代码

p26: 字节顺序是网络编程的基础,记住小端是“高对高、低对低”,大端与之相反就可以了。

p28: (我在后面里运行了这个代码)

p32: 能区分逻辑运算(结果是1或0)和位运算(结果是位向量),所有逻辑运算都可以用与、或、非表达(最大式、最小式),而与或非可以用“与非”或“或非”表达,所以,只要一个与非门,就可以完成所有的逻辑运算。

p33: 掩码是位运算的重要应用,对特定位可以置一,可以清零

p38: 要用C99中的“long long”类型,编译是要用 gcc -std=c99

p39: 补码的利用寄存器的长度是固定的特性简化数学运算。想想钟表,12-1 等价于 12 + 11,利用补码可以把数学运算统一成加法,只要一个加法器就可以实现所有的数学运算。

p44: 注意C语言中有符号数和无符号数的转换规则,位向量不变。想想第一章说的 信息就是“位+上下文”

p48: 怎么样让负数等于正数? 信息安全的逆向思维
第二个是无符号运算的话,第一个也会被隐式地转换为无符号数。

p49: 0扩展和符号扩展

  • 0扩展:多用于无符号数转换为一个更大的数据类型。只需在开头加上0即可。
  • 符号扩展:多用于补码数字转换。最高有效位是什么,就添加什么。

p52: 深入思考一下代码和结果

这个问题是说明从有符号数到无符号数的隐式强制类型转换容易引起错误。

p54: 如何让整数运算溢出?如何避免? p62例子看看

p67: 关于整数运算的最后思考

p67: 浮点数有科学计数法的基础就不难理解,IEEE标准754

p68: 浮点数运算的不精确性与舍入

p70: IEEE浮点标准,float/double类型

p74: 整数与浮点数表示同一个数字的关系

p78: 整数与浮点数转换规则

教材学习中的问题和解决过程

开始的时候以为书上的代码都是全的,在敲第28页的代码的时候,我就觉得这个代码没有主函数怎么会执行?难道是因为要在Linux环境里可以像Java那样可以关联,但是我在后面也没有发现有关这个的代码,果然在执行的时候,它告诉我没有主函数,看来这个就和在Windows系统下的编程没有什么区别都是一样的。

开始的时候吓我一跳,我看出了警告,我还以为程序有问题,后面才想起C语言中在Windows下也有可能有警告,接下来直接执行,是可应用的。

还有在第35页的代码我也发现了一个问题,按照课后习题的答案我将中间的<=改成<就可以解决这个问题,是因为没必要交换正中间的元素和他自己,所以会出现那个错误,但是我只说输入n位,但是在执行的时候却要输入n+1位,计算的时候依旧是前n位,这是为什么?

通过修改代码我发现,我发现是因为通过循环实现,所以是需要来一步步比较的,修改了其中的比较次数就会出现在结果显示的时候不全的问题。

这是本周的代码行数:

本周代码托管截图

本周的个人思考问题

我对于文件指针这里的问题还是很多的,但是目前看了几章来说,我没有发现哪里有什么地方帮助我学习这里缺失的知识,对于一些例子中的代码也是似懂非懂,这该怎么办?

其他(感悟、思考等,可选)

这次学习的内容看似很少,实际上还是比较多的,因为这章有很多代码要在Linux环境下运行,还是要实践很多东西的,并且在这次的代码中,有的代码不是全的,需要大家自己来补充缺失的主函数等部分。
本章的主要内容还是讲了很多细小的知识点,以及进制之间转换或者位级运算的东西,我都在上面记录了很多我认为比较重要的知识点。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 24篇 350小时
第一周 0/0行 1/2 20小时
第二周 53/53行 1/3 25/45小时
第三周 130/183行 1/4 30/75小时

注释

-深入理解计算机系统,实验楼
-Linux基础入门
-Ubuntu下的git使用

原文地址:https://www.cnblogs.com/hanhaochen/p/5920505.html