一次数值越界引起的问题
数值越界是需要引起重视的问题,后端服务没有严格检验请求字段的取值范围,则可能引发严重的后果。
事故
例如用户购买礼物,礼物单价为20金币。有用户购买了1073741825个礼物,却只需要花费20金币,这是为何?
原因
原来系统中设定的购买数量和金币均采用了uint32,uint32的取值范围为[0, 4294967295],显示购买的数量1073741825在uint32的表示范围里。但计算金币时,需要乘以20,则总金币值超过uint32的表达范围,即溢出。
那么我们现在来讲计算一下,购买数量乘以单价1073741825*20=21474836500,用二进制表示为10100000000000000000000000000010100,长度为35位。转换为uint32位,则最高三位举出丢弃,剩下的值为00000000000000000000000000010100,转为十进制为20。因此利用数值溢出的原理,用户就可以在仅仅消费20金币的情况下,购买得到惊人的1073741825个礼物。
补充:原码、反码、补码的表示
原码就是最高位作为符号位,0表示正数,1表示负数,其余位表示真值的绝对值。
反码与原码相比,正数的反码就是原码,负数的反码在原码的基础上,符号位不变,其余位取反。
补码,正数的补码就是原码,负数的补码是反码的基础上加1
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性