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'