编程语言中的数字数据类型都预设了大小,也就是说,一个数字数据类型的变量,总会有能表达的上限,有上限就会有溢出。本篇从二进制的底层,分析解释一下数值溢出问题。以byte为例。


0x01.问题引入

  • 看如下一段Java代码,你能立马说出输出结果吗?
public class Main {public static void main(String[] args) {int a=1888;byte b=(byte) a;System.out.println(b);}
}
  • 或许你只能意识到:反正不是1888,反正不会超过byte能表示的数据范围。
  • 赶紧把代码复制下来编译运行一下,一看输出结果:96
  • 为什么会是96呢?
  • 清楚这个之前,我们不妨去探究一下,底层都干了些什么。

0x02.byte能表示的数据范围

  • 我们都知道,byte能表示的数据范围是:-128-127,但是,为什么是这个范围呢?

  • 原因:在Java中,对于byte类型的变量,JVM会为其分配一个字节的内存,一个字节也就是8位,但是由于最高位是符号位,所以能够表示的数据范围就是 -2^7 --2^7-1。原码,反码,补码知识补充:

    • 原码:最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
    • 反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,符号位除外。
    • 补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1(负数的补码是其绝对值取反)。
    • 在计算机中,用补码表示二进制数。
  • 范围可视化:


  • 其它数值数据类型的范围,跟byte范围的计算,一模一样。

0x03.byte的溢出原理

  • 回到最初的例子,我们看一下那个转换的过程都发生了什么。
  • int类型变量占4个字节的内存,也就是32位,所以它能表示的数据范围是:-2^31--2^31-1
  • 那么a变量在内存中的表示,是这样吗?

  • 必然不是,因为上面说到,一个int类型的变量,占了32位,那么完整的形式应该是:

  • 而此时一个未初始化的byte变量b在内存中应该是:

  • 此时如果进行强制类型转换 b=(byte)a,int类型变量的低8位会给byte,然后int其它位的数据就会丢失。如下:

  • 这也正好解释了最初b的输出问题。

0x04.快速计算溢出后的值

  • 使用二进制去理解原理固然清晰,但是如果都转到二进制计算的话,肯定是会比较复杂的。
  • 我们不如看下它的转换规律:
int a=128;
byte b=(byte) a;
System.out.println(b);
//上述代码输出-128int a=129;
byte b=(byte) a;
System.out.println(b);
//上述代码输出-127int a=383;
byte b=(byte) a;
System.out.println(b);
//上述代码输出127int a=384;
byte b=(byte) a;
System.out.println(b);
//上述代码输出-128int a=-129;byte b=(byte) a;
System.out.println(b);
//上述代码输出127
  • 不难发现,随着int的增大,byte转换后的值都在一个循环内。如下:

  • 可以这样看这个图,在byte范围内127+1=-128-128-1=127

  • 那么整个的计算可以总结为:

    • 若a>127,上界溢出,顺时针循环,那么强转成byte后,若以0为起点,对256取余得到的值,就是在这个圈中从0开始往右走了多少。例如:1888,对256取余得96,相当于从0向右走了96,所以最后的值就是96。1920,对256取余得128,相当于从0向右走了128,所以最后的值就是-128。

    • 若a<-128,下界溢出,逆时针循环,那么强转成byte后,若以0为起点,对256取余得到的值,就是在这个圈中从0开始往左走了多少。例如:-385,对256取余得129,相当于从0开始向左走了129,所以最后的值就是127。依次类推。

  • 只要记住循环圆,计算还是比较简单的。

0x05.推广到所有数值类型的溢出

  • byte的溢出是一个数值溢出的典型例子,其它数值类型因为表示的范围比较大,发生溢出的情况比较少,不过其所有溢出的原理和byte类型一模一样。
  • int类型溢出的例子:
public class Main {public static void main(String[] args) {System.out.println(Integer.MAX_VALUE+1==Integer.MIN_VALUE);//输出true}
}
  • 数值溢出也算是一个很经典的漏洞,如果有数值溢出点,经过攻击者精心的构造利用,可能会造成巨大的损失。具体数值溢出漏洞利用,可以参考:整型溢出漏洞

随时注意数据类型范围很重要哦~~~

【数值溢出】从二进制的角度看数值溢出相关推荐

  1. ES6-11数值扩展:二进制和八进制、数值分隔符、Number.isFinite()、Number.isNaN()等

    1. 二进制和八进制 用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === 503 // true// 非严格模式 (function ...

  2. 汇川plc可以用C语言吗,汇川小型PLC梯形图编程系列教程(七):数值存储与二进制数据知识详解...

    PLC数据存储原理简介 H123U小型PLC内部采用的是32位的处理器,PLC中的数据处理和电脑中的数据处理基本是一致的.所有的CPU进行数据处理时,都是将其他进制的数据转换成二进制数进行加减乘除运算 ...

  3. 汇川小型PLC梯形图编程系列教程(七):数值存储与二进制数据知识详解

    原文链接:汇川小型PLC梯形图编程系列教程(七):数值存储与二进制数据知识详解 PLC数据存储原理简介 H123U小型PLC内部采用的是32位的处理器,PLC中的数据处理和电脑中的数据处理基本是一致的 ...

  4. 运行时错误7内存溢出_分别从运行时和GC的角度看JAVA8内存管理

    运行时区域 1.程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.在虚拟机概念模型里(概念模型,各种虚拟机 ...

  5. 一个数值转化为二进制 位运算和位域

    在嵌入式系统和单片机开发中,数值转化为二进制是非常常用的,对与位域可能很多上层开发人员都 不曾见到,位域在MCU开发中常用的使用的,例如一个开关量和高低电平信号,只用0和1两种状态. 下面是我做项目时 ...

  6. 从JDK源码角度看Long

    概况 Java的Long类主要的作用就是对基本类型long进行封装,提供了一些处理long类型的方法,比如long到String类型的转换方法或String类型到long类型的转换方法,当然也包含与其 ...

  7. go conn 读取byte数组后是否要_【技术推荐】正向角度看Go逆向

    Go语言具有开发效率高,运行速度快,跨平台等优点,因此正越来越多的被攻击者所使用,其生成的是可直接运行的二进制文件,因此对它的分析类似于普通C语言可执行文件分析,但是又有所不同,本文将会使用正向与逆向 ...

  8. 【技术推荐】正向角度看Go逆向

    Go语言具有开发效率高,运行速度快,跨平台等优点,因此正越来越多的被攻击者所使用,其生成的是可直接运行的二进制文件,因此对它的分析类似于普通C语言可执行文件分析,但是又有所不同,本文将会使用正向与逆向 ...

  9. 一般向量空间的基变换_从希尔伯特空间的角度看线性变换的一般思想和问题

    一般线性变换以及傅里叶变换,欧氏变换,仿射变换,余弦变换,小波变换,拉普拉斯变换,Z变换,希尔伯特变换等等这些所谓的变换太多了,这些到底搞得是什么?怎么像云像雾又像风呢?怎么才能彻底理解它们?它们究竟 ...

最新文章

  1. Express2.X迁移至3.X注意事项
  2. Django框架之DRF get post put delete 使用简单示例 (利用序列化反序列化)
  3. 算法题007 计算n的阶乘
  4. 批量部署虚拟机实战解析
  5. java依赖注入_Java依赖注入选项
  6. Java Swing/AWT和GTK混合GUI编程
  7. java处理json的工具类(list,map和json的之间的转换)
  8. R和Tableau平行坐标图
  9. python:查看函数方法的具体信息、参数等
  10. SpringBoot整合调用微信模板方法实现微信公众号消息通知推送,Java实现微信公众号给关注用户推送自定义消息通知(手把手从0到1)
  11. 电信 dns服务器 不稳定,网速不稳定的解决方法:修改本地DNS
  12. 于歆杰pdf 电路原理_buck电路原理(于歆杰 电路原理pdf)
  13. iOS仿苹果原生天气app总结
  14. 微信开发工具出现 [渲染层网络层错误]
  15. ListNode的理解
  16. Tomcat输出框乱码(鏈嶅姟鍣ㄥ湪[463]姣鍐呭垵濮嬪寲)
  17. android 仿小米相机,android-自定义相机遇小米3生成图片花屏
  18. 通过adb模拟快速的屏幕点击,小米手机亲测有效
  19. [C++]char转换为string ,固定长度的char数组转换为string
  20. ubuntu护眼第二大神器 Redshift

热门文章

  1. rhel配置磁盘分区_CentOS/RedHat系统磁盘分区基本要求及分区方案
  2. Easy Problem 9 判断质数
  3. 自考那些事儿(五):软件开发工具(实践篇)
  4. dns劫持,启动chrome就打开垃圾网站
  5. 基于springboot垃圾分类网站
  6. python remove pop
  7. 解决win10更新后vmware无法启动问题
  8. 做亚马逊应该怎么去选品?怎么找货源?
  9. DNA配对找对象?为了让年轻人结婚生孩子,日本有多拼?
  10. 视频教程-Ajax从入门到进阶视频课程(通俗易懂)-JavaScript