Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #286 from lzpap/trytestring_randomlength
Browse files Browse the repository at this point in the history
Use class length for random TryteString generation
  • Loading branch information
lzpap committed Jan 14, 2020
2 parents 41cc47a + cb8c9e2 commit 6e0b5c2
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 4 deletions.
5 changes: 5 additions & 0 deletions iota/crypto/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ class Seed(TryteString):
- https://iota.stackexchange.com/q/249
"""

LEN = 81
"""
Length of a Seed.
"""

def __init__(self, trytes=None):
# type: (Optional[TrytesCompatible]) -> None
if trytes and len(trytes) > Hash.LEN:
Expand Down
15 changes: 12 additions & 3 deletions iota/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,28 @@ class TryteString(JsonSerializable):
"""

@classmethod
def random(cls, length):
# type: (int) -> TryteString
def random(cls, length=None):
# type: (Optional[int]) -> TryteString
"""
Generates a random sequence of trytes.
:param int length:
:param Optional[int] length:
Number of trytes to generate.
:return:
:py:class:`TryteString` object.
"""
alphabet = list(itervalues(AsciiTrytesCodec.alphabet))
generator = SystemRandom()
try:
if length is None:
length = cls.LEN

if length <= 0:
raise TypeError("length parameter needs to be greater than zero")
except AttributeError: # class has no LEN attribute
if length is None:
raise TypeError("{class_name} does not define a length property".format(class_name=cls.__name__))

# :py:meth:`SystemRandom.choices` wasn't added until Python 3.6;
# for compatibility, we will continue to use ``choice`` in a
Expand Down
13 changes: 13 additions & 0 deletions test/crypto/types_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ def test_init_error_too_short(self):
with self.assertRaises(ValueError):
Digest(b'9' * (2 * Hash.LEN - 1))

def test_random(self):
"""
Generating a random Digest should fail.
"""
with self.assertRaises(TypeError):
random_digest = Digest.random()

# noinspection SpellCheckingInspection
class PrivateKeyTestCase(TestCase):
Expand Down Expand Up @@ -152,3 +158,10 @@ def test_get_digest_multiple_fragments(self):
#
# Each fragment is processed independently, which is critical for
# multisig to work correctly.

def test_random(self):
"""
Generating a random PrivateKey should fail.
"""
with self.assertRaises(TypeError):
random_digest = PrivateKey.random()
42 changes: 41 additions & 1 deletion test/transaction/types_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

from six import binary_type

from iota import TransactionHash
from iota import TransactionHash, BundleHash, Fragment, TransactionTrytes, \
Nonce


class TransactionHashTestCase(TestCase):
Expand Down Expand Up @@ -39,3 +40,42 @@ def test_init_error_too_long(self):
b'JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOK'
b'HXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC99999'
)

def test_random(self):
"""
Creating a random TransactionHash object.
"""
random_tx_hash = TransactionHash.random()
self.assertEqual(len(random_tx_hash), TransactionHash.LEN)

class BundleHashTestCase(TestCase):
def test_random(self):
"""
Creating a random BundleHash object.
"""
random_bundle_hash = BundleHash.random()
self.assertEqual(len(random_bundle_hash), BundleHash.LEN)

class FragmentTestCase(TestCase):
def test_random(self):
"""
Creating a random Fragment object.
"""
random_fragment = Fragment.random()
self.assertEqual(len(random_fragment), Fragment.LEN)

class TransactionTrytesTestCase(TestCase):
def test_random(self):
"""
Creating a random TransactionTrytes object.
"""
random_tx_trytes = TransactionTrytes.random()
self.assertEqual(len(random_tx_trytes), TransactionTrytes.LEN)

class NonceTestCase(TestCase):
def test_random(self):
"""
Creating a random Nonce object.
"""
random_nonce = Nonce.random()
self.assertEqual(len(random_nonce), Nonce.LEN)
42 changes: 42 additions & 0 deletions test/types_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,20 @@ def test_random(self):
# generated.
self.assertEqual(len(trytes), Hash.LEN)

def test_random_no_length(self):
"""
Trying to create a random TryteString without specifying length.
"""
with self.assertRaises(TypeError):
trytes = TryteString.random()

def test_random_wrong_length(self):
"""
Generating random Trytestring with negative length.
"""
with self.assertRaises(TypeError):
trytes = TryteString.random(length=-5)

def test_from_bytes(self):
"""
Converting a sequence of bytes into a TryteString.
Expand Down Expand Up @@ -883,6 +897,14 @@ def test_from_trits_wrong_length_padded(self):
b'RBTC',
)

class HashTestCase(TestCase):
def test_random(self):
"""
Generating a random Hash.
"""
rand = Hash.random()
self.assertEqual(len(rand), Hash.LEN)


# noinspection SpellCheckingInspection
class AddressTestCase(TestCase):
Expand Down Expand Up @@ -1124,6 +1146,12 @@ def test_remove_checksum_second_time(self):
self.assertFalse(addy.is_checksum_valid())
self.assertTrue(len(addy) == Address.LEN)

def test_random(self):
"""
Creating a random Address object.
"""
addy = Address.random()
self.assertEqual(len(addy), Address.LEN)

# noinspection SpellCheckingInspection
class AddressChecksumTestCase(TestCase):
Expand All @@ -1149,6 +1177,13 @@ def test_init_error_too_long(self):
# If it's an address checksum, it must be 9 trytes exactly.
AddressChecksum(b'FOXM9MUBX9')

def test_random(self):
"""
Creating a random AddressChecksum object.
"""
checksum = AddressChecksum.random()
self.assertEqual(len(checksum), AddressChecksum.LEN)


# noinspection SpellCheckingInspection
class TagTestCase(TestCase):
Expand All @@ -1167,3 +1202,10 @@ def test_init_error_too_long(self):
with self.assertRaises(ValueError):
# 28 chars = no va.
Tag(b'COLOREDCOINS9999999999999999')

def test_random(self):
"""
Creating a random Tag object.
"""
tag = Tag.random()
self.assertEqual(len(tag), Tag.LEN)

0 comments on commit 6e0b5c2

Please sign in to comment.