Skip to content

Commit ce50237

Browse files
committed
JavaScript to Python is 60% completed
1 parent 5bc77d1 commit ce50237

2 files changed

Lines changed: 57 additions & 19 deletions

File tree

js2pysecrets/base.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,15 @@ def padLeft(string, multipleOfBits=None):
4242
new_length = -(-len(string) // multipleOfBits) * multipleOfBits
4343
return string.zfill(new_length)
4444

45-
46-
47-
# def padLeft(string, multipleOfBits):
48-
# if multipleOfBits and isinstance(multipleOfBits, int)
49-
# and multipleOfBits > 1:
50-
# multipleOfBits = multipleOfBits or settings.bits
51-
# return string.zfill(-(-len(str) // multipleOfBits) * multipleOfBits)
52-
5345

5446
def bin2hex(binary_string: str) -> str:
55-
return hex(int(binary_string, 2))
47+
hex_string = hex(int(binary_string, 2))[2:]
48+
hex_string = hex_string.zfill((len(padLeft(binary_string, 4)) // 4))
49+
return hex_string
5650

5751

5852
def hex2bin(hex_string: str) -> str:
59-
return bin(int(hex_string, 16))
53+
return bin(int(hex_string, 16))[2:]
6054

6155

6256
"""
@@ -164,6 +158,18 @@ def init(bits=None, rngType=None):
164158
"""
165159

166160

161+
def hasCryptoGetRandomValues():
162+
# Browser supports crypto.getRandomValues()
163+
# Depreciated - Not Applicable for Python Version
164+
return False # pragma: no cover
165+
166+
167+
def hasCryptoRandomBytes():
168+
# Node.js support for crypto.randomBytes()
169+
# Depreciated - Not Applicable for Python Version
170+
return False # pragma: no cover
171+
172+
167173
def getRNG():
168174
if isinstance(settings.rng, str):
169175
return lambda bits: (bin(123456789)[2:].zfill(32) * -(-bits // 32))[
@@ -267,6 +273,17 @@ def getConfig():
267273
return settings.get_config()
268274

269275

276+
def random(bits):
277+
if not isinstance(bits, int) or bits < 2 or bits > 65536:
278+
raise ValueError(
279+
"Number of bits must be an Integer between 1 and 65536."
280+
)
281+
282+
rng = getRNG()
283+
284+
return bin2hex(rng(bits))
285+
286+
270287
# # Core Functions from secrets.js
271288
# init = jsFunction('init')
272289
# combine = jsFunction('combine')

tests/test_basePrivate.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ def test_str2hex_bytes():
116116

117117

118118
def test_hex2str(random_string, bytes_per_char):
119-
# Convert random_string to bytes using specified encoding
120-
# byte_string = random_string.encode(encoding)
121-
122119
# Perform conversion using str2hex function
123120
py_hex = secrets.str2hex(str(random_string), bytes_per_char)
124121
js_hex = node.str2hex(str(random_string), bytes_per_char)
@@ -264,8 +261,6 @@ def test_getRNG(input_range):
264261

265262
@pytest.mark.parametrize("input_range", range(random.randrange(1, 2047)))
266263
def test_node_py_getRNG(input_range):
267-
# block_size = int(2048 / (input_range + 1))
268-
# bits = (block_size * (input_range + 1)) - random.randrange(0, block_size)
269264
bits = bit_range(input_range)
270265
secrets.init()
271266
secrets.setRNG("testRandom")
@@ -281,8 +276,6 @@ def test_node_py_getRNG(input_range):
281276

282277
@pytest.mark.parametrize("input_range", range(random.randrange(1, 2047)))
283278
def test_node_py_lengthRNG(input_range):
284-
# block_size = int(2048 / (input_range + 1))
285-
# bits = (block_size * (input_range + 1)) - random.randrange(0, block_size)
286279
bits = bit_range(input_range)
287280
secrets.init()
288281
assert secrets.isSetRNG() == True
@@ -490,11 +483,19 @@ def multiple_numbers(request):
490483
return request.param
491484

492485

486+
def test_padLeft_Fail():
487+
match = "Padding must be multiples of no larger than 1024 bits."
488+
with pytest.raises(ValueError, match=match):
489+
secrets.padLeft("101010101110", 1025)
490+
# Check if any warnings were raised
491+
assert len(caught_warnings) == 1
492+
assert issubclass(caught_warnings[0].category, Warning)
493+
assert match in str(caught_warnings[0].message)
494+
495+
493496
def test_node_py_padLeft_spotCheck():
494497
py_command = secrets.getRNG()
495498
py_random = py_command(11)
496-
# py_string = secrets.padLeft(py_random, multiple_numbers)
497-
# js_string = node._padLeft(py_random, multiple_numbers)
498499
assert len(secrets.padLeft(py_random, 0)) == 11
499500
assert len(secrets.padLeft(py_random, 1)) == 11
500501
assert len(secrets.padLeft(py_random, 3)) == 12
@@ -506,6 +507,7 @@ def test_node_py_padLeft_spotCheck():
506507

507508

508509
def test_node_py_padLeft(prime_numbers, multiple_numbers):
510+
secrets.init()
509511
py_command = secrets.getRNG()
510512
py_random = py_command(prime_numbers)
511513
py_string = secrets.padLeft(py_random, multiple_numbers)
@@ -514,3 +516,22 @@ def test_node_py_padLeft(prime_numbers, multiple_numbers):
514516
assert len(py_string) == len(js_string)
515517
assert (len(py_string) % multiple_numbers) == 0
516518
assert (len(js_string) % multiple_numbers) == 0
519+
520+
521+
def random_range(input_range):
522+
block_size = int(65536 / (input_range + 1))
523+
# bits = (block_size * (input_range + 1)) - random.randrange(0, block_size)
524+
bits = (1 + block_size) - random.randrange(0, block_size)
525+
return bits
526+
527+
528+
# @pytest.mark.parametrize("input_range", range(random.randrange(2, 128)))
529+
@pytest.mark.parametrize("input_range", range(300))
530+
def test_py_js_random(input_range):
531+
# bits = random_range(input_range)
532+
bits = int(input_range * 188) + 2
533+
secrets.init()
534+
secrets.setRNG("testRandom")
535+
py_string = secrets.random(bits)
536+
js_string = node.random(bits, test=True)
537+
assert py_string == js_string

0 commit comments

Comments
 (0)