zoukankan      html  css  js  c++  java
  • 20145212 《信息安全系统设计基础》第3周学习总结

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

    教材学习内容总结

    1.进制

    • 二进制、八进制、十进制、十六进制(转换:以二进制作为中间变量)

    2.字

    • 每台计算机都有一个字长,指明整数和指针数据的大小。
    • 虚拟地址是以这样的一个字来编码的,字长决定虚拟地址空间的最大大小。

    3.字节顺序

    • 小端法——在存储器中按照从最低有效字节到最高有效字节的顺序存储对象。
    • 大端法——从最高有效字节到最低有效字节的顺序存储。

    4.布尔代数

    • (1)二进制值是计算机编码、存储、操作信息的核心(0、1),最简单的布尔代数是在二元集合{0,1}上的定义。
    • (2)一个布尔代数,是指一个有序的四元组〈B,∨,∧,〉,其中B是一个非空的集合,∨与∧是定义在B上的两个二元运算,是定义在B上的一个一元运算,并且它们满足一定的条件。
    • (3)布尔值有两个,真(用1表示)和假(用0表示)。
    • (4)布尔值的基本运算是基本逻辑运算,如:逻辑与,逻辑或,逻辑非,异或,同或等等。有自己的一套概念如最大项、最小项、卡诺图、反演律、吸收律之类。

    5.整数表示

    • 数据类型long long是在ISO C99中引入的。(编译:gcc -std=c99)。
    • 64位机器用8个字节表示;32位机器用4个字节表示。
    • 负数的范围比整数的范围大1。

    6.补码

    • 补码是最常见的有符号数的计算机表示方式。
    正数的补码=原码
    负数的补码=原码各位取反再加1
    最高有效位也叫符号位。
    

    7.无符号数与有符号数转换

    • 强制类型转换的结果保持位值不变,改变解释这些位的方式。
    • 处理同样字长的有、无符号数之间相互转换的规则:数值可能会变,但是位模式不变。(底层的位表示保持不变)
    无————>有:U2Tw函数
    有————>无:T2Uw函数
    
    • 注:w表示数据类型的位数。

    8.扩展数字的位表示

    • 零扩展:在开头添0。(将无符号数转换成更大的数据类型)
    • 符号扩展:添加最高有效位的值的副本。(一个补码数字转换成更大的数据类型)

    9.截断数字

    • 可能会改变数值——溢出的一种形式。

    • 对于无符号数字x,截断到k位,相当于计算:x mod 2(k)。(k次幂)

    10.整数运算

    • 整数运算实际上是一种模运算形式。表示数字的有限字长限制了可能的值得取值,结果可能溢出。
    • 溢出:一个算术运算的溢出——完整的整数结果不能放到数据类型的字长限制中。

    11.浮点数:标准:IEEE标准754

    (1)二进制小数
    定点表示法:“.”为界(不能有效的表示很大的数)

    十进制:小数点左边的数字的权是10的非负幂,得到整数值;右边的数字的权是10的负幂,得到小数值。
    二进制:小数点左边的数字的权是2的非负幂,右边的数字的权是2的负幂。
    

    (2)IEEE浮点表示

    ●用V = (-1)s * M * 2E的形式来表示一个数:

    符号:s决定这个数是负数(s = 1)还是正数(s = 0),而对于数值0的符号位解释作为特殊情况处理。
    尾数:M是一个二进制小数,它的范围是1 ~ 2-ε,或者是0 ~ 1-ε。
    阶码:E的作用是对浮点数据加权,这个权重是2的E次幂(可能是负数)。
    

    ●将浮点数的位表示划分为三个字段,分别对这些值进行编码:

    一个单独的符号位s直接编码符号s。
    k位的阶码字段exp = ek-1…e1e0编码阶码E。
    n位小数字段frac = fn-1…f1f0编码尾数M,但是编码出来的值也依赖于阶码字段的值是否等于0。
    

    ●两种常见的格式:C语言中的单精度浮点格式float 和双精度浮点格式double。

    在float中,s、exp和frac字段分别为1位、k = 8 位和n = 23位,得到一个32位的表示;
    在double中,s、exp和frac字段分别为1位、k = 11 位和n = 52位,得到一个64位的表示。
    

    教材学习中的问题及总结

    1.从逆向角度考虑为什么无符号数、有符号数(2进制补码)、浮点数之间的转换会产生漏洞?
    任何漏洞产生都必然因为系统不可更改的局限性——>无符号数、有符号数、浮点数的局限性——>无符号数或者有符号数的表示范围有限,而浮点数虽然编码范围大,但是不精确。
    2.怎么样让负数等于正数?
    在负数x后加上U,可以使其转换为(2^w+x)
    3.整数与浮点数表示同一个数字的关系?
    整数与浮点数表示同一个数字时,化成二进制形式之后,可以看到,整数等于1 的最高有效位之后的数字,与浮点数小数部分的高位是相匹配的
    4.当阶码全为1、小数域全为0时,得到的值表示无穷;当阶码全为1、小数域不全为0时,结果是NaN(not a number)
    5.整数与浮点数转换规则?
    整数->浮点数:整数转换成二进制表示,然后小数点左移若干位得到规格化表示;取出小数部分的数值,在后面补0使其达到23位; 用frac加上偏置量得到的结果用二进制表示,放在取出的部分前面,再加上一个符号位即可。

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

    重点练习

    1.p28,show_bytes,写个main函数测试一下,参考p30代码

    • 添加部分的代码如下:
    • 运行结果:

    2.p35 练习2.11, 可以用GDB单步跟踪一下,理解更深刻

    • 代码如下:
    #include<stdio.h>
    #define MAX 10
    void inplace_swap(int *x,int *y)
    {
        *y = *x^*y;
        *x = *x^*y;
        *y = *x^*y;
    }
    void reverse_array(int a[], int cnt)
    {
        int first,last;
        for(first = 0,last = cnt-1;first<=last;first++,last--)
            inplace_swap(&a[first], &a[last]);
    }
    void main()
    {
        int a[MAX];
        int count,i;
        printf("please enter the amount of numbers( no more than %d):
    ",MAX);
        scanf("%d",&count);
        printf("please enter any number as the end
    ");
        for(i = 1;i<=count;i++)
        {
            scanf("%d
    ",&a[i-1]);
        }
        printf("the original array is as follow:
    ");
        for(i = 1;i<=count;i++)
        {
            printf("%d  ",a[i-1]);
        }
        reverse_array(a, count);
        printf("the new array is as follow:
    ");
        for(i = 1;i<=count;i++)
        {
            printf("%d  ",a[i-1]);
        }
    }
    
    • 运行结果:

    • 此时发现,在输入奇数个数的时候,中间元素会是0,原因是什么?
      答:由于在最后一次调用inplace_swap的时候,传入的first和last都是原数组中最中间的数字;在第一处*y = x^y时,y指向的数字就变为了0。此后,0变作为最中间的数字参与循环。解决办法只需要将循环条件中的first<=last 改为first<last(最中间的数字不会参与循环)即可。

    3.p44,有符号数和无符号数的转换,代码放到一个main函数中,并用GDB单步跟踪

    • 运行结果

    4.p47/p49代码放到一个main函数中

    • 代码部分:
    • 运行结果:

    家庭作业

    2.58 编写过程is_little_endian,当在小端法机器上编译和运行时返回1,在大端法机器上编译运行时返回0.这个程序可以运行在任何机器上,无论机器的字长是多少。

    int is_little_endian(){
        int x = 1;
        char y=(char)x; 
        return y
    }
    

    2.65写出代码实现如下函数:
    Return 1 when x contains an even number of 1s; 0 otherwise. Assume w=32
    int even_ones(unsigned x);
    函数应该遵循位级整数编码规则,不过你可以假设数据类型int有w=32位,你的代码最多只能包含12个算术运算、位运算和逻辑运算。

    • 解读题目:当无符号数x包含偶数个1时,返回值为1,否则为返回值为0,假设x的数据类型是int 有w=32位。
    • 解题思路:要求x所包含的1的个数,可以对x的每个位进行异或运算。如果得到的结果是0,那么就说明x包含偶数个1,则返回值为1,;如果得到的结果是1,那么说明x包含奇数个1,则返回值为0。
    • 代码编写过程:由于x是个32位int类型数,所以
      ①首先采用折半缩小规模的方法进行逐位异或;
      ②最后得到的x值再与1进行与运算就会得到一个32位中前31均为0,尾数是0或者是1(用于判断是原x包含奇数还是偶数个1);
      ③返回这个值就完成了题目需求。
    • 代码编写:
    int even_ones(unsigned x){
    x ^= (x >> 16);//等同于x=x^(x>>16)
    x ^= (x >> 8); //等同于x=x^(x>>8)
    x ^= (x >> 4); //等同于x=x^(x>>4)
    x ^= (x >> 2); //等同于x=x^(x>>2)
    x ^= (x >> 1); //等同于x=x^(x>>1)
    return !(x&1);
    }
    

    截图:

    • 运行结果如下:

      即当a为10e5+0时,返回值为0
      若a为10e5+1时,返回值为1

    本周代码托管截图

    (因为在老师说要单个程序commit -m之前就已经上传完毕了,所以是一起传的代码,下次会注意。)

    http://git.oschina.net/alovera/week03

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

    这一周的学习主要是操作系统中的信息表示和处理,乍一看上去十分复杂枯燥,但是这些知识却是我们学习编程的基础中的基础,一定要清楚概念和运算转换方式。

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 0/0 1/2 10/10
    第二周 300/300 1/3 20/30
    第三周 300/600 2/5 16/46

    参考资料

  • 相关阅读:
    解决clickonce不支持administer权限问题
    好好了解一下Cookie(强烈推荐)
    Cookie的存储读取删除修改 (cookie.Expires读取永远是零时间)
    14VUE插槽
    13VUE非父子组件传值
    1VUE学习方法
    11VUE监听原生事件
    10VUE,组件参数校验,组件3
    9,Vue组件2
    8.VUE计数器,基于组件
  • 原文地址:https://www.cnblogs.com/alovera/p/5903015.html
Copyright © 2011-2022 走看看