View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.benerator.primitive;
28  
29  import com.rapiddweller.benerator.GeneratorContext;
30  import com.rapiddweller.benerator.IllegalGeneratorStateException;
31  import com.rapiddweller.benerator.distribution.Distribution;
32  import com.rapiddweller.benerator.util.LuhnUtil;
33  import com.rapiddweller.benerator.wrapper.NonNullGeneratorProxy;
34  import com.rapiddweller.common.StringUtil;
35  
36  /**
37   * Generates numbers that pass a Luhn test.<br/><br/>
38   * Created: 18.10.2009 10:08:09
39   *
40   * @author Volker Bergmann
41   * @since 0.6.0
42   */
43  public class LuhnGenerator extends NonNullGeneratorProxy<String> {
44  
45    /**
46     * The Prefix.
47     */
48    protected String prefix;
49    /**
50     * The Min length.
51     */
52    protected int minLength;
53    /**
54     * The Max length.
55     */
56    protected int maxLength;
57    /**
58     * The Length granularity.
59     */
60    protected final int lengthGranularity;
61    /**
62     * The Length distribution.
63     */
64    protected final Distribution lengthDistribution;
65  
66    /**
67     * Instantiates a new Luhn generator.
68     */
69    public LuhnGenerator() {
70      this("", 16);
71    }
72  
73    /**
74     * Instantiates a new Luhn generator.
75     *
76     * @param prefix the prefix
77     * @param length the length
78     */
79    public LuhnGenerator(String prefix, int length) {
80      this(prefix, length, length, 1, null);
81    }
82  
83    /**
84     * Instantiates a new Luhn generator.
85     *
86     * @param prefix             the prefix
87     * @param minLength          the min length
88     * @param maxLength          the max length
89     * @param lengthGranularity  the length granularity
90     * @param lengthDistribution the length distribution
91     */
92    public LuhnGenerator(String prefix, int minLength, int maxLength, int lengthGranularity, Distribution lengthDistribution) {
93      super(String.class);
94      this.prefix = prefix;
95      this.minLength = minLength;
96      this.maxLength = maxLength;
97      this.lengthGranularity = 1;
98      this.lengthDistribution = lengthDistribution;
99    }
100 
101   /**
102    * Sets prefix.
103    *
104    * @param prefix the prefix
105    */
106   public void setPrefix(String prefix) {
107     this.prefix = prefix;
108   }
109 
110   /**
111    * Sets min length.
112    *
113    * @param minLength the min length
114    */
115   public void setMinLength(int minLength) {
116     this.minLength = minLength;
117   }
118 
119   /**
120    * Sets max length.
121    *
122    * @param maxLength the max length
123    */
124   public void setMaxLength(int maxLength) {
125     this.maxLength = maxLength;
126   }
127 
128   @Override
129   public synchronized void init(GeneratorContext context) {
130     super.setSource(new RandomVarLengthStringGenerator("\\d", minLength, maxLength, lengthGranularity, lengthDistribution));
131     super.init(context);
132   }
133 
134   @Override
135   public String generate() throws IllegalGeneratorStateException {
136     String number = super.generate();
137     if (!StringUtil.isEmpty(prefix)) {
138       number = prefix + number.substring(prefix.length());
139     }
140     char checkDigit = LuhnUtil.requiredCheckDigit(number);
141     if (StringUtil.lastChar(number) == checkDigit) {
142       return number;
143     } else {
144       return number.substring(0, number.length() - 1) + checkDigit;
145     }
146   }
147 
148 }