# Thu, 20 Aug 2026 13:11:52 GMT
---
version: 23
data:


- type: ModificationMethod
  attributes:
    displayName: Pattern
    description: |
          Generates a sequence of letters and digits according to a pattern.The letter 'A' is replaced by a letter from A to Z.The digit '9' is replaced by a digit from 0 to 9.The letter 'N' is replaced by either a letter or a digit.The letter 'X' is replaced by a hexadecimal digit (0 to F).All other characters are preserved as they are.
    scriptLanguage: "GROOVY"
    legacyScript: false
    inputType: "COLUMN"
    mappingTableContainers: []
    mappingTableAccessMode: READ
    code: |
        /*
         * *****************************************************************************
         * Pattern
         * *****************************************************************************
         *
         * The following variables are available in this script:
         * =====================================================
         * ctx             : A context object that offers a number of methods.
         *                   The method indexOf() can be used to get the index of a
         *                   specific column within the data.
         * data       : The data array. This array contains the contents of all
         *                   columns of the current row of the table that is being
         *                   masked by this method.
         *
         * Additionally for column based modification methods the following two
         * variables are available:
         * columnName      : The name of the column that matched the modificationMethod.pattern.
         * columnIndex     : The position of the column that matched the modificationMethod.pattern within
         *                   the data array. This value is zero-based.
         * *****************************************************************************
         */
        import de.ubs.xdm3.batch.modification.HashUtils
        
        /*
         * This function is called once before the processing starts. The method
         * is called once per table.
         */
        def init() {
        
        }
        
        /*
         * This function should modify the row that is provided by the data. The
         * method is called for each single row of the table.
         */
        def apply() {
        
            def seedValue = modificationMethod.seed
            def ALNUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXZY"
            def ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXZY"
            def DIGITS = "0123456789"
            def HEX    = "0123456789ABCDEF"
            def value = seedValue.toString().trim()
            def h = HashUtils.hashStringLikeInt(value)
            h = HashUtils.hashInt(h)
            def r = ""
        
            modificationMethod.pattern.each { c ->
                switch (c) {
                    case '9':
                        r += DIGITS[ h % DIGITS.size() ]
                        break
                    case 'A':
                        r += ALPHABET[ h % ALPHABET.size() ]
                        break
                    case 'X':
                        r += HEX[ h % HEX.size() ]
                        break
                    case 'N':
                        r += ALNUM[ h % ALNUM.size() ]
                        break
                    default:
                        r += c
                }
                h = HashUtils.hashInt(h)
            }
            data[columnIndex] = r
            return true
        }
        
        /*
         * This function is executed once after the modification of a table is complete. The method
         * is called once per table.
         */
        def close() {
        }
    parameters:
    - displayName: Seed
      description: |
          Specifies the value that is used to calculate the hash.
      variableName: seed
      dataType: STRING
    - displayName: Pattern
      description: |
          The pattern string based upon which the resulting sequence of letters and digits will be calculated.
      variableName: pattern
      dataType: STRING
