一次数值越界引起的问题

数值越界是需要引起重视的问题,后端服务没有严格检验请求字段的取值范围,则可能引发严重的后果。

事故

例如用户购买礼物,礼物单价为20金币。有用户购买了1073741825个礼物,却只需要花费20金币,这是为何?

原因

原来系统中设定的购买数量和金币均采用了uint32,uint32的取值范围为[0, 4294967295],显示购买的数量1073741825在uint32的表示范围里。但计算金币时,需要乘以20,则总金币值超过uint32的表达范围,即溢出。

那么我们现在来讲计算一下,购买数量乘以单价1073741825*20=21474836500,用二进制表示为10100000000000000000000000000010100,长度为35位。转换为uint32位,则最高三位举出丢弃,剩下的值为00000000000000000000000000010100,转为十进制为20。因此利用数值溢出的原理,用户就可以在仅仅消费20金币的情况下,购买得到惊人的1073741825个礼物。

补充:原码、反码、补码的表示

原码就是最高位作为符号位,0表示正数,1表示负数,其余位表示真值的绝对值。
反码与原码相比,正数的反码就是原码,负数的反码在原码的基础上,符号位不变,其余位取反。
补码,正数的补码就是原码,负数的补码是反码的基础上加1

posted @   g2012  阅读(305)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示