package main import ( "errors" "fmt" "go-nkode/models" "go-nkode/util" ) // TODO: make generic type CustomerAttributes struct { AttrVals []uint64 SetVals []uint64 keypadSize models.KeypadSize } func NewCustomerAttributes(keypadSize models.KeypadSize) (*CustomerAttributes, error) { if keypadSize.IsDispersable() { return nil, errors.New("number of keys must be less than the number of attributes per key to be dispersion resistant") } attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(keypadSize.TotalAttrs()) if errAttr != nil { return nil, errAttr } setVals, errSet := util.GenerateRandomNonRepeatingUint64(keypadSize.AttrsPerKey) if errSet != nil { return nil, errSet } customerAttrs := CustomerAttributes{ AttrVals: attrVals, SetVals: setVals, keypadSize: keypadSize, } return &customerAttrs, nil } func (c *CustomerAttributes) Renew() error { attrVals, errAttr := util.GenerateRandomNonRepeatingUint64(c.keypadSize.TotalAttrs()) if errAttr != nil { return errAttr } setVals, errSet := util.GenerateRandomNonRepeatingUint64(c.keypadSize.AttrsPerKey) if errSet != nil { return errSet } c.AttrVals = attrVals c.SetVals = setVals return nil } func (c *CustomerAttributes) IndexOfAttr(attrVal uint64) int { // TODO: should this be mapped instead? return util.IndexOf[uint64](c.AttrVals, attrVal) } func (c *CustomerAttributes) IndexOfSet(setVal uint64) (int, error) { // TODO: should this be mapped instead? idx := util.IndexOf[uint64](c.SetVals, setVal) if idx == -1 { return -1, errors.New(fmt.Sprintf("Set Val %d is invalid", setVal)) } return idx, nil } func (c *CustomerAttributes) GetAttrSetVal(attrVal uint64) (uint64, error) { indexOfAttr := c.IndexOfAttr(attrVal) if indexOfAttr == -1 { return 0, errors.New(fmt.Sprintf("No attribute %d", attrVal)) } setIdx := indexOfAttr % c.keypadSize.AttrsPerKey return c.SetVals[setIdx], nil }