[tor-commits] [stem/master] Adding _to_int() helper to str_tools
atagar at torproject.org
atagar at torproject.org
Thu Mar 30 04:18:03 UTC 2017
commit 15ed89f92087d50c0646b373e8c43153948550e9
Author: Damian Johnson <atagar at torproject.org>
Date: Tue Mar 21 21:40:51 2017 +0100
Adding _to_int() helper to str_tools
Replacing our cert module's _bytes_to_long() helper with a tested counterpart
in str_tools. Not sure if it matters but should be more efficient. Rather than
doing a 'unicode => bytes => hex => int' conversion we directly convert to the
integer representation.
---
stem/descriptor/certificate.py | 18 ++++++------------
stem/util/str_tools.py | 16 ++++++++++++++++
test/unit/util/str_tools.py | 17 +++++++++++++++++
3 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py
index 528d594..191e87e 100644
--- a/stem/descriptor/certificate.py
+++ b/stem/descriptor/certificate.py
@@ -2,8 +2,8 @@
# See LICENSE for licensing information
"""
-Parsing for the Tor server descriptor Ed25519 Certificates, which is used to
-validate the Ed25519 key used to sign the relay descriptor.
+Parsing for Tor Ed25519 certificates, which is used to validate the key used to
+sign server descriptors.
Certificates can optionally contain CertificateExtension objects depending on
their type and purpose. Currently Ed25519KeyCertificate certificates will
@@ -41,16 +41,9 @@ CERTIFICATE_FLAGS_LENGTH = 4
ED25519_ROUTER_SIGNATURE_PREFIX = b'Tor router descriptor signature v1'
-def _bytes_to_long(b):
- if stem.prereq.is_python_3():
- return int(binascii.hexlify(stem.util.str_tools._to_bytes(b)), 16)
- else:
- return long(binascii.hexlify(b), 16)
-
-
def _parse_long_offset(offset, length):
def _parse(raw_contents):
- return _bytes_to_long(raw_contents[offset:(offset + length)])
+ return stem.util.str_tools._to_int(raw_contents[offset:(offset + length)])
return _parse
@@ -82,7 +75,8 @@ def _parse_certificate(raw_contents, master_key_bytes, validate = False):
def _parse_extensions(raw_contents):
- n_extensions = _bytes_to_long(raw_contents[39:40])
+ n_extensions = stem.util.str_tools._to_int(raw_contents[39:40])
+
if n_extensions == 0:
return []
@@ -90,7 +84,7 @@ def _parse_extensions(raw_contents):
extension_bytes = raw_contents[STANDARD_ATTRIBUTES_LENGTH:-SIGNATURE_LENGTH]
while len(extension_bytes) > 0:
- ext_length = _bytes_to_long(extension_bytes[0:2])
+ ext_length = stem.util.str_tools._to_int(extension_bytes[0:2])
ext_type = extension_bytes[2:3]
ext_flags = extension_bytes[3:CERTIFICATE_FLAGS_LENGTH]
ext_data = extension_bytes[CERTIFICATE_FLAGS_LENGTH:(CERTIFICATE_FLAGS_LENGTH + ext_length)]
diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py
index 0fbdf38..8c6463a 100644
--- a/stem/util/str_tools.py
+++ b/stem/util/str_tools.py
@@ -117,6 +117,22 @@ def _to_unicode(msg):
return _to_unicode_impl(msg)
+def _to_int(msg):
+ """
+ Serializes a string to a number.
+
+ :param str msg: string to be serialized
+
+ :returns: **int** representation of the string
+ """
+
+ if stem.prereq.is_python_3() and isinstance(msg, bytes):
+ # iterating over bytes in python3 provides ints rather than characters
+ return sum([pow(256, (len(msg) - i - 1)) * c for (i, c) in enumerate(msg)])
+ else:
+ return sum([pow(256, (len(msg) - i - 1)) * ord(c) for (i, c) in enumerate(msg)])
+
+
def _to_camel_case(label, divider = '_', joiner = ' '):
"""
Converts the given string to camel case, ie:
diff --git a/test/unit/util/str_tools.py b/test/unit/util/str_tools.py
index 3d0936f..00e5c55 100644
--- a/test/unit/util/str_tools.py
+++ b/test/unit/util/str_tools.py
@@ -9,6 +9,23 @@ from stem.util import str_tools
class TestStrTools(unittest.TestCase):
+ def test_to_int(self):
+ """
+ Checks the _to_int() function.
+ """
+
+ test_inputs = {
+ '': 0,
+ 'h': 104,
+ 'hi': 26729,
+ 'hello': 448378203247,
+ str_tools._to_bytes('hello'): 448378203247,
+ str_tools._to_unicode('hello'): 448378203247,
+ }
+
+ for arg, expected in test_inputs.items():
+ self.assertEqual(expected, str_tools._to_int(arg))
+
def test_to_camel_case(self):
"""
Checks the _to_camel_case() function.
More information about the tor-commits
mailing list