param_source: allow input val expansion like '0 * 32'

Working with keys, we often generate 4, 8, 16, 32 digit wide random
values. Those then typically have default input values like

 00000000000000000000000000000000

it is hard for humans to count the number of digits. Much easier:

 00*16

Teach the ParamSource subclasses dealing with random values to
understand an expansion like this. Any expansion is carried out before
all other input value handling.

Use this expansion also in the default_value of ConfigurableParameter
subclasses that have a default_source pointing at a ParamSource that now
understand this expansion.

Related: SYS#6768
Change-Id: Ie7171c152a7b478736f8825050305606b5af5735
This commit is contained in:
Neels Hofmeyr
2025-03-08 02:12:47 +01:00
parent d5e550dcc4
commit 9bdf1e3dee
2 changed files with 32 additions and 7 deletions

View File

@@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import random import random
import re
class ParamSourceExn(Exception): class ParamSourceExn(Exception):
pass pass
@@ -59,7 +60,28 @@ class ConstantSource(ParamSource):
def get_next(self, csv_row:dict=None): def get_next(self, csv_row:dict=None):
return self.val return self.val
class DecimalRangeSource(ParamSource): class InputExpandingParamSource(ParamSource):
@classmethod
def expand_str(cls, s:str):
# user convenience syntax '0*32' becomes '00000000000000000000000000000000'
if "*" not in s:
return s
tokens = re.split(r"([^ \t]+)[ \t]*\*[ \t]*([0-9]+)", s)
if len(tokens) < 3:
return s
parts = []
for unchanged, snippet, repeat_str in zip(tokens[0::3], tokens[1::3], tokens[2::3]):
parts.append(unchanged)
repeat = int(repeat_str)
parts.append(snippet * repeat)
return "".join(parts)
@classmethod
def from_str(cls, s:str):
return cls(cls.expand_str(s))
class DecimalRangeSource(InputExpandingParamSource):
"""abstract: decimal numbers with a value range""" """abstract: decimal numbers with a value range"""
def __init__(self, num_digits, first_value, last_value): def __init__(self, num_digits, first_value, last_value):
@@ -83,8 +105,10 @@ class DecimalRangeSource(ParamSource):
@classmethod @classmethod
def from_str(cls, s:str): def from_str(cls, s:str):
s = cls.expand_str(s)
if ".." in s: if ".." in s:
first_str, last_str = s.split("..") first_str, last_str = s.split('..')
first_str = first_str.strip() first_str = first_str.strip()
last_str = last_str.strip() last_str = last_str.strip()
else: else:
@@ -103,7 +127,7 @@ class RandomDigitSource(DecimalRangeSource):
val = random.randint(*self.val_first_last) # TODO secure random source? val = random.randint(*self.val_first_last) # TODO secure random source?
return self.val_to_digit(val) return self.val_to_digit(val)
class RandomHexDigitSource(ParamSource): class RandomHexDigitSource(InputExpandingParamSource):
"""return a different sequence of random hexadecimal digits each""" """return a different sequence of random hexadecimal digits each"""
name = "random hexadecimal digits" name = "random hexadecimal digits"
@@ -123,6 +147,7 @@ class RandomHexDigitSource(ParamSource):
@classmethod @classmethod
def from_str(cls, s:str): def from_str(cls, s:str):
s = cls.expand_str(s)
return cls(num_digits=len(s.strip())) return cls(num_digits=len(s.strip()))
class IncDigitSource(DecimalRangeSource): class IncDigitSource(DecimalRangeSource):

View File

@@ -700,7 +700,7 @@ class Puk(DecimalHexParam):
allow_len = 8 allow_len = 8
rpad = 16 rpad = 16
keyReference = None keyReference = None
example_input = '0' * allow_len example_input = f'0*{allow_len}'
default_source = param_source.RandomDigitSource default_source = param_source.RandomDigitSource
@classmethod @classmethod
@@ -736,7 +736,7 @@ class Pin(DecimalHexParam):
rpad = 16 rpad = 16
min_len = 4 min_len = 4
max_len = 8 max_len = 8
example_input = '0' * max_len example_input = f'0*{max_len}'
default_source = param_source.RandomDigitSource default_source = param_source.RandomDigitSource
keyReference = None keyReference = None
@@ -776,7 +776,7 @@ class Pin(DecimalHexParam):
class Pin1(Pin): class Pin1(Pin):
name = 'PIN1' name = 'PIN1'
example_input = '0' * 4 # PIN are usually 4 digits example_input = '0*4' # PIN are usually 4 digits
keyReference = 0x01 keyReference = 0x01
class Pin2(Pin1): class Pin2(Pin1):
@@ -881,7 +881,7 @@ class K(BinaryParam, AlgoConfig):
name = 'K' name = 'K'
algo_config_key = 'key' algo_config_key = 'key'
allow_len = (128 // 8, 256 // 8) # length in bytes (from BinaryParam); TUAK also allows 256 bit allow_len = (128 // 8, 256 // 8) # length in bytes (from BinaryParam); TUAK also allows 256 bit
example_input = '00' * allow_len[0] example_input = f'00*{allow_len[0]}'
class Opc(K): class Opc(K):
name = 'OPc' name = 'OPc'