복붙노트

[REDIS] 루아 비트 32 개 비트 연산을 사용하는 64 비트 값을 비교 서명

REDIS

루아 비트 32 개 비트 연산을 사용하는 64 비트 값을 비교 서명

나는 레디 스에 루아를 사용하여 2 개의 8 바이트 / 문자열에 저장되어있는 두 개의 서명 64 비트 숫자를 비교하고자하고있다.

어떻게 레디 스에서 사용할 수있는 라이브러리를 사용하여 비교할 수있다?  http://redis.io/commands/EVAL#available-libraries

나는> / <와 == 검사를 알고 싶습니다. 나는 이것이 아마 각 64 비트 INT 두 개의 32 비트 숫자를 당겨, 그 일부 영리한 수학을하고 관련 생각하지만, 나는 확실하지 않다.

나는이 덜 추상적 할 몇 가지 코드가 있습니다. A0, A1, B0, B1은 최상위 비트 및 두 개의 64 비트 부호 INT의 64S의 LSB의 표시에 사용하는 모든 32 개 비트 값이다 :

-- ...
local comp_int64s = function (a0, a1, b0, b1)
    local cmpres = 0
    -- TOOD: Real comparison
    return cmpres
end
local l, a0, a1, b0, b1
a0, l = bit.tobit(struct.unpack("I4", ARGV[1]))
a1, l = bit.tobit(struct.unpack("I4", ARGV[1], 5))
b0, l = bit.tobit(struct.unpack("I4", blob))
b1, l = bit.tobit(struct.unpack("I4", blob, 5))
print("Cmp result", comp_int64s(a0, a1, b0, b1))

편집 : 추가 된 코드

해결법

  1. ==============================

    1.나는 그것과 같은 모습이 일하고있는 방법을 함께했다. 그것은 조금 추한 생각합니다.

    나는 그것과 같은 모습이 일하고있는 방법을 함께했다. 그것은 조금 추한 생각합니다.

    제 2 단계는 보체 #의 최상위로 32 비트를 비교하는 것이다 MSB 기호 숙박 비트, 그래서 번호는 올바른 관계를 유지

    -1  —> -1
    0 —> 0
    9223372036854775807 = 0x7fff ffff ffff ffff -> 0x7ffff ffff = 2147483647
    

    가 동일하지 않는 한 다음, LSB의 필요를 MSB의 작품에서 결과를 반환 그래서 확인하세요.

    나는 몇 가지 패턴을 설정하는 몇 가지 경우가 있습니다

    -1 = 0xffff ffff ffff ffff
    -2 = 0xffff ffff ffff fffe
    32 bit is:
    -1 -> 0xffff ffff = -1
    -2 -> 0xffff fffe = -2
    -1 > -2 would be like -1 > -2 : GOOD
    

    8589934591 = 0x0000 0001 ffff ffff
    8589934590 = 0x0000 0001 ffff fffe
    32 bit is:
    8589934591 -> ffff ffff = -1
    8589934590 -> ffff fffe = -2
    8589934591 > 8589934590 would be -1 > -2 : GOOD
    

    MSB의의 부호 비트는 B / C 음 번호는 양수로 자신과 같은 관계가 중요하지 않습니다. 예컨대에 관계없이 부호 비트의 LSB를 0xFF> 내지 0xFE의 값, 항상.

    무엇 하위 32 비트의 MSB가 다른 경우는 어떻습니까?

    0xff7f ffff 7fff ffff = -36,028,799,166,447,617
    0xff7f ffff ffff ffff = -36,028,797,018,963,969
    32 bit is:
    -..799.. -> 0x7fff ffff = 2147483647
    -..797.. -> 0xffff ffff = -1
    -..799.. < -..797.. would be 2147483647 < -1 : BAD!
    

    그래서 우리는 하위 32 비트에 부호 비트를 무시해야합니다. 관계에 관계없이 기호의 LSB를위한 동일하기 때문에 그리고, 단지 사용 가장 낮은 32 비트는 모든 경우에 대한 작품을 부호없는.

    나는 LSB를위한 MSB의위한 서명과 서명되지 않은하려는이 방법은 - 그래서 LSB를위한 I4에 I4 들어간 상태. 또한 빅 엔디안 공식을하고 struct.unpack 호출에 '>'를 사용 :

    -- ...
    local comp_int64s = function (as0, au1, bs0, bu1)
        if as0 > bs0 then
            return 1
        elseif as0 < bs0 then
            return -1
        else
            -- msb's equal comparing lsbs - these are unsigned
            if au1 > bu1 then
                return 1
            elseif au1 < bu1 then
                return -1
            else
                return 0
            end
        end
    end
    local l, as0, au1, bs0, bu1
    as0, l = bit.tobit(struct.unpack(">i4", ARGV[1]))
    au1, l = bit.tobit(struct.unpack(">I4", ARGV[1], 5))
    bs0, l = bit.tobit(struct.unpack(">i4", blob))
    bu1, l = bit.tobit(struct.unpack(">I4", blob, 5))
    print("Cmp result", comp_int64s(as0, au1, bs0, bu1))
    
  2. ==============================

    2.간단한 문자열 S1 == S2를 비교한다 비교.

    간단한 문자열 S1 == S2를 비교한다 비교.

    보다 큰 경우되지 S1 및 S2 == I1

    이하는 실제 작업이다. string.byte은 서명 숯불로 단일 바이트를 얻을 수 있습니다. 부호없는 정수의 경우, 당신은 단지 바이트 - 아래를 확인해야합니다 : B1 == B2가 -> 다음의 바이트를 확인; 모든 바이트 관통 -> (동일) 오류; B1> B2 -> 거짓 (보다 크다); B1 참. 서명은 더 많은 단계가 필요합니다 먼저 부호 비트를 확인 (최상위 바이트> 127). > 사실 - 기호 1 만 설정되어있는 경우 (1)가 부정하지만이 정수가 아닌이 정수 2에 서명하지. 반대는 분명히 거짓을 초래할 것입니다. 모두 표시이 동일하면 서명 처리를 할 수 있습니다.

    당신이 정수에 더 많은 바이트를 포장 할 수 때, 너무 괜찮습니다,하지만 당신은 부호 비트 체크를 조정해야합니다. 당신이 LuaJIT이있을 때, 당신은 INT64로 바이트 배열로 문자열을 캐스팅하기 위해 FFI 라이브러리를 사용할 수 있습니다.

  3. from https://stackoverflow.com/questions/35488855/comparing-signed-64-bit-number-using-32-bit-bitwise-operations-in-lua by cc-by-sa and MIT license