Skip to content

Commit bf71770

Browse files
committed
Added more functions and tests
1 parent 9aa7c43 commit bf71770

4 files changed

Lines changed: 110 additions & 15 deletions

File tree

.flake8

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[flake8]
22
per-file-ignores =
3-
js2pysecrets/settings.py:E731
3+
js2pysecrets/settings.py:E731
4+
js2pysecrets/base.py:E203

gems/defaults3.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
print(data)
4545

4646

47-
print(secrets.str2hex('hello world', 2))
48-
print(node.str2hex('hello world', 2))
47+
foo = secrets.str2hex('hello world', 2)
48+
bar = node.str2hex('hello world', 2)
4949

50+
print(secrets.hex2str(bar))
51+
print(node.hex2str(foo))

js2pysecrets/base.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ def str2hex(string, bytes_per_char=None):
9090
f"Bytes per character must be an integer between 1 and "
9191
f"{defaults.max_bytes_per_char}, inclusive."
9292
)
93-
# raise Exception(
94-
# "Bytes per character must be an integer between 1 and "
95-
# "{defaults.max_bytes_per_char}, inclusive."
96-
# )
9793

9894
hex_chars = 2 * bytes_per_char
9995
max_val = 16**hex_chars - 1
@@ -117,6 +113,43 @@ def str2hex(string, bytes_per_char=None):
117113
return out
118114

119115

116+
def hex2str(hex_string, bytes_per_char=None):
117+
if not isinstance(hex_string, str):
118+
raise ValueError("Input must be a hexadecimal string.")
119+
120+
defaults = settings.get_defaults()
121+
122+
# defaults = {"bytes_per_char": 2, "max_bytes_per_char": 4}
123+
# Assuming these defaults
124+
125+
bytes_per_char = bytes_per_char or defaults.bytes_per_char
126+
127+
if (
128+
not isinstance(bytes_per_char, int)
129+
or bytes_per_char % 1 != 0
130+
or bytes_per_char < 1
131+
or bytes_per_char > defaults.max_bytes_per_char
132+
):
133+
raise ValueError(
134+
f"Bytes per character must be an integer between 1 and "
135+
f"{defaults.max_bytes_per_char}, inclusive."
136+
)
137+
138+
hex_chars = 2 * bytes_per_char
139+
140+
# Pad left if necessary
141+
hex_string = hex_string.zfill(
142+
len(hex_string) + (hex_chars - len(hex_string) % hex_chars) % hex_chars
143+
)
144+
145+
out = ""
146+
for i in range(0, len(hex_string), hex_chars):
147+
char_code = int(hex_string[i : i + hex_chars], 16)
148+
out = chr(char_code) + out
149+
150+
return out
151+
152+
120153
def getConfig():
121154
settings.update_defaults(hasCSPRNG=isSetRNG())
122155
return settings.get_config()

tests/test_basePrivate.py

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ def test_get_config():
3434

3535
@pytest.fixture(
3636
params=[
37+
faker.name(),
38+
faker.password(),
39+
faker.pystr(),
3740
faker.sentence(),
3841
faker.text(max_nb_chars=160),
39-
faker.pystr(),
40-
faker.password(),
41-
faker.name(),
4242
# Add more options as needed
4343
]
4444
)
@@ -56,16 +56,29 @@ def bytes_per_char(request):
5656
return request.param
5757

5858

59-
def test_str2hex(random_string, encoding, bytes_per_char):
59+
def test_str2hex(random_string, bytes_per_char):
6060
# Convert random_string to bytes using specified encoding
61-
byte_string = random_string.encode(encoding)
61+
# byte_string = random_string.encode(encoding)
6262

6363
# Perform conversion using str2hex function
64-
py_string = secrets.str2hex(str(byte_string), bytes_per_char)
65-
js_string = secrets.str2hex(str(byte_string), bytes_per_char)
64+
# string = str(byte_string)
65+
py_hex = secrets.str2hex(str(random_string), bytes_per_char)
66+
js_hex = node.str2hex(str(random_string), bytes_per_char)
6667

6768
# Perform your assertions on hex_representation
68-
assert py_string == js_string
69+
assert py_hex == js_hex
70+
71+
72+
def test_str2hex_utf8():
73+
# Use the string from the JavaScript tests
74+
key = "¥ · £ · € · $ · ¢ · ₡ · ₢ · ₣ · ₤ · ₥ · ₦ · ₧ · ₨ · ₩ · ₪ · ₫ · ₭ · ₮ · ₯ · ₹"
75+
76+
# Perform conversion using str2hex function
77+
py_hex = secrets.str2hex(key)
78+
js_hex = node.str2hex(key)
79+
80+
# Perform your assertions on hex_representation
81+
assert py_hex == js_hex
6982

7083

7184
def test_str2hex_input():
@@ -85,3 +98,49 @@ def test_str2hex_bytes():
8598
assert len(caught_warnings) == 1
8699
assert issubclass(caught_warnings[0].category, Warning)
87100
assert match in str(caught_warnings[0].message)
101+
102+
103+
def test_hex2str(random_string, bytes_per_char):
104+
# Convert random_string to bytes using specified encoding
105+
# byte_string = random_string.encode(encoding)
106+
107+
# Perform conversion using str2hex function
108+
py_hex = secrets.str2hex(str(random_string), bytes_per_char)
109+
js_hex = node.str2hex(str(random_string), bytes_per_char)
110+
111+
# Perform your assertions on hex_representation
112+
assert py_hex == js_hex
113+
114+
# Perform conversion using hex2str function py~py/js~js
115+
py_value = secrets.hex2str(py_hex, bytes_per_char)
116+
js_value = node.hex2str(js_hex, bytes_per_char)
117+
assert py_value == str(random_string)
118+
assert js_value == str(random_string)
119+
assert py_value == js_value
120+
121+
# Perform conversion using hex2str function py~js/js~py
122+
py_string = secrets.hex2str(js_hex, bytes_per_char)
123+
js_string = node.hex2str(py_hex, bytes_per_char)
124+
assert py_string == str(random_string)
125+
assert js_string == str(random_string)
126+
assert py_string == js_string
127+
128+
129+
def test_hex2str_input():
130+
match = "Input must be a hexadecimal string."
131+
with pytest.raises(ValueError, match=match):
132+
secrets.hex2str(1234)
133+
assert len(caught_warnings) == 1
134+
assert issubclass(caught_warnings[0].category, Warning)
135+
assert match in str(caught_warnings[0].message)
136+
137+
138+
def test_hex2str_bytes():
139+
match = "must be an integer between 1 and 6"
140+
with pytest.raises(ValueError, match=match):
141+
string = secrets.str2hex("foobar")
142+
secrets.hex2str(string, 7)
143+
# Check if any warnings were raised
144+
assert len(caught_warnings) == 1
145+
assert issubclass(caught_warnings[0].category, Warning)
146+
assert match in str(caught_warnings[0].message)

0 commit comments

Comments
 (0)