From 9bdf1e3deef97760a79dc6f5bd0d59985e2ea0b3 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Sat, 8 Mar 2025 02:12:47 +0100 Subject: [PATCH] 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 --- pySim/esim/saip/param_source.py | 31 +++++++++++++++++++++++++++--- pySim/esim/saip/personalization.py | 8 ++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/pySim/esim/saip/param_source.py b/pySim/esim/saip/param_source.py index 77f2e1cc..01a8cb00 100644 --- a/pySim/esim/saip/param_source.py +++ b/pySim/esim/saip/param_source.py @@ -18,6 +18,7 @@ # along with this program. If not, see . import random +import re class ParamSourceExn(Exception): pass @@ -59,7 +60,28 @@ class ConstantSource(ParamSource): def get_next(self, csv_row:dict=None): 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""" def __init__(self, num_digits, first_value, last_value): @@ -83,8 +105,10 @@ class DecimalRangeSource(ParamSource): @classmethod def from_str(cls, s:str): + s = cls.expand_str(s) + if ".." in s: - first_str, last_str = s.split("..") + first_str, last_str = s.split('..') first_str = first_str.strip() last_str = last_str.strip() else: @@ -103,7 +127,7 @@ class RandomDigitSource(DecimalRangeSource): val = random.randint(*self.val_first_last) # TODO secure random source? return self.val_to_digit(val) -class RandomHexDigitSource(ParamSource): +class RandomHexDigitSource(InputExpandingParamSource): """return a different sequence of random hexadecimal digits each""" name = "random hexadecimal digits" @@ -123,6 +147,7 @@ class RandomHexDigitSource(ParamSource): @classmethod def from_str(cls, s:str): + s = cls.expand_str(s) return cls(num_digits=len(s.strip())) class IncDigitSource(DecimalRangeSource): diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py index 0c91f49f..75d619b4 100644 --- a/pySim/esim/saip/personalization.py +++ b/pySim/esim/saip/personalization.py @@ -700,7 +700,7 @@ class Puk(DecimalHexParam): allow_len = 8 rpad = 16 keyReference = None - example_input = '0' * allow_len + example_input = f'0*{allow_len}' default_source = param_source.RandomDigitSource @classmethod @@ -736,7 +736,7 @@ class Pin(DecimalHexParam): rpad = 16 min_len = 4 max_len = 8 - example_input = '0' * max_len + example_input = f'0*{max_len}' default_source = param_source.RandomDigitSource keyReference = None @@ -776,7 +776,7 @@ class Pin(DecimalHexParam): class Pin1(Pin): name = 'PIN1' - example_input = '0' * 4 # PIN are usually 4 digits + example_input = '0*4' # PIN are usually 4 digits keyReference = 0x01 class Pin2(Pin1): @@ -881,7 +881,7 @@ class K(BinaryParam, AlgoConfig): name = 'K' algo_config_key = 'key' 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): name = 'OPc'