mirror of
https://github.com/status-im/nim-stew.git
synced 2025-01-09 11:45:42 +00:00
Add constant isEqual operation for openarrays.
This commit is contained in:
parent
ec2f52b0ce
commit
a5560c1ea6
35
stew/ctops.nim
Normal file
35
stew/ctops.nim
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
## Copyright (c) 2020 Status Research & Development GmbH
|
||||||
|
## Licensed under either of
|
||||||
|
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
|
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
## at your option.
|
||||||
|
## This file may not be copied, modified, or distributed except according to
|
||||||
|
## those terms.
|
||||||
|
|
||||||
|
## This module implements different operations which will execute in amount of
|
||||||
|
## time (or memory space) independent of the input size.
|
||||||
|
|
||||||
|
type
|
||||||
|
CT* = object
|
||||||
|
AnyByte* = byte | char
|
||||||
|
|
||||||
|
proc isEqual*[A: AnyByte, B: AnyByte](c: typedesc[CT], a: openArray[A],
|
||||||
|
b: openArray[B]): bool {.
|
||||||
|
raises: [Defect] .} =
|
||||||
|
## Perform constant time comparison of two arrays ``a`` and ``b``.
|
||||||
|
##
|
||||||
|
## Please note that it only makes sense to compare arrays of the same length.
|
||||||
|
## If length of arrays is not equal only part of array will be compared.
|
||||||
|
##
|
||||||
|
## Procedure returns ``true`` if arrays of same length are equal or
|
||||||
|
## part of array's content is equal to another array's content if arrays
|
||||||
|
## lengths are different.
|
||||||
|
##
|
||||||
|
## Beware that arrays ``a`` and ``b`` MUST NOT BE empty.
|
||||||
|
doAssert(len(a) > 0 and len(b) > 0)
|
||||||
|
var count = min(len(a), len(b))
|
||||||
|
var res = 0
|
||||||
|
while count > 0:
|
||||||
|
dec(count)
|
||||||
|
res = res or int(int(a[count]) xor int(b[count]))
|
||||||
|
(res == 0)
|
@ -20,4 +20,5 @@ import
|
|||||||
test_objects,
|
test_objects,
|
||||||
test_ptrops,
|
test_ptrops,
|
||||||
test_results,
|
test_results,
|
||||||
test_varints
|
test_varints,
|
||||||
|
test_ctops
|
||||||
|
55
tests/test_ctops.nim
Normal file
55
tests/test_ctops.nim
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import unittest
|
||||||
|
import ../stew/ctops
|
||||||
|
|
||||||
|
suite "Constant-time operations test suite":
|
||||||
|
test "isEqual() test":
|
||||||
|
let
|
||||||
|
charArr1 = ['T', 'E', 'S', 'T']
|
||||||
|
charArr2 = ['A', 'B', 'C', 'D']
|
||||||
|
charArr3 = ['B', 'I', 'G', 'M', 'E', 'S', 'S', 'A', 'G', 'E']
|
||||||
|
charArr4 = ['T', 'E', 'S', 'T', 'B', 'I', 'G']
|
||||||
|
charArr5 = ['B', 'I', 'G', 'T', 'E', 'S', 'T']
|
||||||
|
byteArr1 = [0x54'u8, 0x45'u8, 0x53'u8, 0x54'u8]
|
||||||
|
byteArr2 = [0x41'u8, 0x42'u8, 0x43'u8, 0x44'u8]
|
||||||
|
byteArr3 = [0x42'u8, 0x49'u8, 0x47'u8, 0x4D'u8, 0x45'u8,
|
||||||
|
0x53'u8, 0x53'u8, 0x41'u8, 0x47'u8, 0x45'u8]
|
||||||
|
byteArr4 = [0x54'u8, 0x45'u8, 0x53'u8, 0x54'u8, 0x42'u8,
|
||||||
|
0x49'u8, 0x47'u8]
|
||||||
|
byteArr5 = [0x42'u8, 0x49'u8, 0x47'u8, 0x54'u8, 0x45'u8,
|
||||||
|
0x53'u8, 0x54'u8]
|
||||||
|
str1 = "TEST"
|
||||||
|
str2 = "ABCD"
|
||||||
|
str3 = "BIGMESSAGE"
|
||||||
|
str4 = "TESTBIG"
|
||||||
|
str5 = "BIGTEST"
|
||||||
|
seq1 = @byteArr1
|
||||||
|
seq2 = @byteArr2
|
||||||
|
seq3 = @byteArr3
|
||||||
|
seq4 = @byteArr4
|
||||||
|
seq5 = @byteArr5
|
||||||
|
|
||||||
|
check:
|
||||||
|
CT.isEqual(charArr1, charArr1) == true
|
||||||
|
CT.isEqual(charArr1, byteArr1) == true
|
||||||
|
CT.isEqual(charArr1, str1) == true
|
||||||
|
CT.isEqual(charArr1, seq1) == true
|
||||||
|
|
||||||
|
CT.isEqual(byteArr1, charArr2) == false
|
||||||
|
CT.isEqual(byteArr1, byteArr2) == false
|
||||||
|
CT.isEqual(byteArr1, str2) == false
|
||||||
|
CT.isEqual(byteArr1, seq2) == false
|
||||||
|
|
||||||
|
CT.isEqual(str1, charArr3) == false
|
||||||
|
CT.isEqual(str1, byteArr3) == false
|
||||||
|
CT.isEqual(str1, str3) == false
|
||||||
|
CT.isEqual(str1, seq3) == false
|
||||||
|
|
||||||
|
CT.isEqual(seq1, charArr4) == true
|
||||||
|
CT.isEqual(seq1, byteArr4) == true
|
||||||
|
CT.isEqual(seq1, str4) == true
|
||||||
|
CT.isEqual(seq1, seq4) == true
|
||||||
|
|
||||||
|
CT.isEqual(byteArr1, charArr5) == false
|
||||||
|
CT.isEqual(str1, byteArr5) == false
|
||||||
|
CT.isEqual(seq1, str5) == false
|
||||||
|
CT.isEqual(charArr1, seq5) == false
|
Loading…
x
Reference in New Issue
Block a user