V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
hxnets
V2EX  ›  问与答

C# PHP JS 位移运算的结果不一致

  •  
  •   hxnets · 2019-11-29 10:34:20 +08:00 · 1820 次点击
    这是一个创建于 1848 天前的主题,其中的信息可能已经有所发展或是发生改变。

    对接一个系统,要求进行位移加密,结果发现 C#和 PHP 的结果不一致,在 c# 中 3233857544>>-171,结果是 1542,在 PHP 中位移是不允许使用负数的,在 js 中可以运行,但是结果是 3233857544>>-506,因为目标结果其实是根据 C#为基准的,现在开发使用的是 PHP,导致结果不一致,双方验证失败,现在不考虑 php 的位移运算,在 php 中使用 js 代码进行位移计算,怎么能让 js 和 c#的运行结果一致呢?

    16 条回复    2019-11-29 17:19:09 +08:00
    hxnets
        1
    hxnets  
    OP
       2019-11-29 10:38:49 +08:00
    有没有大神知道怎么解决啊
    Delon
        2
    Delon  
       2019-11-29 10:42:38 +08:00
    位移负数这是什么骚操作...
    chenset
        3
    chenset  
       2019-11-29 10:44:24 +08:00
    3233857544 , 类型不对或者溢出了吧
    xenme
        4
    xenme  
       2019-11-29 10:55:33 +08:00   ❤️ 3
    类型问题。
    JS 的默认类型是 Number 是浮点数,位移空位不填零

    Zero-fill right shift a >>> b Shifts a in binary representation b (< 32) bits to the right, discarding bits shifted off, and shifting in 0s from the left.
    JS==========
    3233857544>>>-171
    1542
    hxnets
        5
    hxnets  
    OP
       2019-11-29 11:01:29 +08:00
    @Delon 结算结果就是负数我也崩溃啊 就算是正数俩的结果也不一致
    hxnets
        6
    hxnets  
    OP
       2019-11-29 11:02:47 +08:00
    @xenme 卧槽 真大佬,666 感谢感谢
    RHxW
        7
    RHxW  
       2019-11-29 11:42:12 +08:00   ❤️ 1
    右移有两种,算术右移和逻辑右移,C 中默认>>操作根据操作数类型由编译器判断采用哪种右移,基于 signed 和 unsigned
    js 里应该是用>>和>>>来手动区分逻辑右移和算术右移
    3233857544 算术右移-171 位( 21 位)的结果是-506,逻辑右移-171 位( 21 位)的结果是 1542
    hxnets
        8
    hxnets  
    OP
       2019-11-29 11:59:43 +08:00
    @RHxW 那么我应该怎么判断现在是需要算术右移还是逻辑右移呢?
    RHxW
        9
    RHxW  
       2019-11-29 13:31:59 +08:00
    @hxnets
    绝大多数情况下(甚至是强制地),对有符号数采用算数右移,对无符号数采用逻辑右移
    hxnets
        10
    hxnets  
    OP
       2019-11-29 13:32:48 +08:00
    @RHxW 嗯嗯 好的大佬,左移右移是一样的吧
    RHxW
        11
    RHxW  
       2019-11-29 13:38:55 +08:00   ❤️ 1
    @hxnets
    hhhh 不一样,左移只有一种,就是用 0 补
    逻辑右移和左移一样用 0 补(就是方向不同)
    算术右移是用最高位补,最高位是 1 就用 1 补,是 0 就用 0 补
    hxnets
        12
    hxnets  
    OP
       2019-11-29 15:20:16 +08:00
    @RHxW 完全听不懂,太高深了,大佬就是大佬。
    RHxW
        13
    RHxW  
       2019-11-29 15:41:40 +08:00
    @hxnets
    hhh 这个一点也不高深,只要记住就好了,而且你可以手动将负的位移数转成正的,就可以用 php 直接得出结果了
    hxnets
        14
    hxnets  
    OP
       2019-11-29 16:11:54 +08:00
    @RHxW 还有这种操作?大佬教我 怎么手动转正
    RHxW
        15
    RHxW  
       2019-11-29 16:28:34 +08:00   ❤️ 1
    @hxnets
    求 M>>a (a<0)
    1. 找到 n(n>=1), 令 2^(n-1)<|a|<=2^n
    2. 令 b=2^n - |a|
    3. b = b mod 32(32 是 M 的位数,也有可能 64,看 M 是什么类型了)
    4. 则 M>>a == M>>b

    比如 3233857544>>-171
    找到比 171 大的第一个 2^n,是 256
    256-171=85
    85 mod 32 = 21
    所以 3233857544>>-171 == 3233857544>>21
    hxnets
        16
    hxnets  
    OP
       2019-11-29 17:19:09 +08:00
    @RHxW 牛逼克斯啦 666 我去试试大神
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   974 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:15 · PVG 04:15 · LAX 12:15 · JFK 15:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.