2017-2018-1 20155326 《信息安全系统设计基础》第三周学习总结

教材学习内容总结

  • 学习目标

1)p22三种数字:无符号数、有符号数(2进制补码)、浮点数,信息安全系同学从逆向角度考虑为什么会产生漏洞

无符号编码是基于传统的二进制表示法,表示大于或者等于零的数字。

补码编码是表示有符号整数的最常见方式,有符号整数就是可以为正或者负的数字。

浮点数编码就是表示实数的科学计数法的以2为基数的版本。


产生漏洞的原因:

整数运算和浮点数运算有完全不同的数学属性,因为他们处理数字表现有限性的方式不同。整数的表示虽然只能编码一个相对较小的数值范围,但这种表示是精确的;而浮点数虽然可以编码一个较大的数值范围,但是这种表示只是近似的。

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

在c语言中,以0x或0X开头的数字常量被认为是十六进制的值。二进制、十进制、十六进制的转换拿二进制做跳板就能轻松完成。

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

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

小端法:指在内存中按照从最低有效字节到最高有效字节的顺序存储;大端法反之。

下图是运行2—4和2-5代码得到的3510593十六进制的小端法值。

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

逻辑运算:

位运算:

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

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

8)

无符号数编码定义及展示例子:

补码编码定义及展示例子:

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

补码范围是不对称的,|TMin|=|TMax|+1;

反码和原码定义:

用程序输出12345的原码和反码十六进制表示。

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

数值可能改变,但是为模式不变。

10)p50: 怎么样让负数等于正数? 信息安全的逆向思维

可以编写程序,当一个数a为正数时,令a=~a+1,当a为负数时,令a=~(a-1)。

11)p54: 0扩展和符号扩展

零扩展:将一个无符号数转换为一个更大的数据类型,在表示的开头添加“0”

符号扩展:将一个补码数字转换为一个更大的数据类型,在表示的开头添加最高有效位的值。

如下图所示:

-12345使用了符号扩展,最开头加了16个1,后者使用零扩展,使用了16个0。

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

整数运算溢出可能有以下原因:表示数字的有限字长限制了可能的值的取值范围,结果运算可能溢出;C 语言中的某些规定(比如unsigned数据类型),也可能是产生某些难以察觉的缺陷的源头。

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

14)p77: 浮点数运算的不精确性与舍入

15)p8: IEEE浮点标准,float/double类型

IEEE浮点标准: 用V=(-1)^s * 2^E * M的形式来表示一个数

符号:s决定这个数是正数还是负数(0的符号位特殊处理)  

尾数:M是一个二进制小数,范围为1~2-ε或者0~1-ε(ε=1/2的n次幂)

阶码:E对浮点数加权,这个权重是2的E次幂(可能为负)

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

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

int转换为float,数字不会溢出但可能会舍入

int或float转换成double,double有更大的范围和精度所以可保留精确的数值

double转为float,可能溢出也可能舍入

float或double转为int,值会向零舍入且可能溢出

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

(一个模板:我看了这一段文字 (引用文字),有这个问题 (提出问题)。 我查了资料,有这些说法(引用说法),根据我的实践,我得到这些经验(描述自己的经验)。 但是我还是不太懂,我的困惑是(说明困惑)。【或者】我反对作者的观点(提出作者的观点,自己的观点,以及理由)。 )

  • 问题1:p52 运行代码:

    int x=-1;
    unsigned u=2147483648;
    printf("x=%u=%d\n",x,x);
    printf("u=%u=%d\n",u,u);

我看了这一段代码,不懂为什么u=2147483648=-2147483648。

  • 问题1解决方案:查看了书上的解析后明白2147483648=2^31 >(231-1),所以-2147483648是由231-232=-231得到的。

  • 问题2:P56 练习2-23看不明白两者的区别。

  • 问题2解决方案:我能看出来fun1函数是将两次移位后的数进行强制类型转换,fun2函数是将第一次移位后的数进行强制类型转换再移位,但我不知道那个移位是怎么移的,所以我在百度上查了逻辑移位和算术移位的区别,得知算术移位指令对带符号数进行移位,逻辑移位指令对无符号数进行移位;算术左移同逻辑左移,算术右移移入的位用符号位填。在这道题中,fun1是无符号数的移位,所以是逻辑移位;fun2是有符号数的移位所以是算术移位。

代码调试中的问题和解决过程

  • 问题1:在试着运行p31 2-4和2-5的代码时,运行出错。
  • 问题1解决方案:试了很多次以后才发现他们不是完整的函数,加一个主函数就好啦。

代码托管

(statistics.sh脚本的运行结果截图)

家庭作业

我完成的是*2.55:在不同的机器上,使用show_bytes.c编译并运行示例代码。确定这些机器使用的字节顺序。

这是在我电脑的虚拟机上运行的结果:

由图可知我的机器使用的是小端法。

结对及互评

点评模板:

  • 博客中值得学习的或问题:
    • xxx
    • xxx
    • ...
  • 代码中值得学习的或问题:
    • xxx
    • xxx
    • ...
  • 其他

本周结对学习情况

- [20155320](博客链接)
- 结对照片

- 结对学习内容
    -教材第二章的内容包括练习题
    - ...

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

我觉得我这周的博客写的挺好的,教材按着重点看的很细,教材执导的勾的习题也做了,但是我觉得我的收获很小,比起老师授课讲解来的太慢了。就像我把题都做了书也看了,我还是对知识了解的不够透彻。我的速度不快,看书做题花了挺多时间的,我觉得这样很低效,其实我还是希望老师教课为主,自学为辅。继续加油吧!

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 2000行 15篇 400小时
第一周 0/0 1/1 10/20
第二周 57/100 1/1 20/30
第三周 100/100 1/1 30/30

尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

参考:软件工程软件的估计为什么这么难软件工程 估计方法

  • 计划学习时间:30小时

  • 实际学习时间:30小时

  • 改进情况:

(有空多看看现代软件工程 课件
软件工程师能力自我评价表
)

参考资料