diff --git a/src/main/java/net/datafaker/idnumbers/HungarianIdNumber.java b/src/main/java/net/datafaker/idnumbers/HungarianIdNumber.java new file mode 100644 index 000000000..dc05cb666 --- /dev/null +++ b/src/main/java/net/datafaker/idnumbers/HungarianIdNumber.java @@ -0,0 +1,86 @@ +package net.datafaker.idnumbers; + +import net.datafaker.providers.base.BaseProviders; +import net.datafaker.providers.base.IdNumber; +import net.datafaker.providers.base.PersonIdNumber; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import static java.lang.Character.getNumericValue; +import static net.datafaker.idnumbers.Utils.randomGender; + +/** + * Hungarian personal identification number + *
+ * The structure of such number is GYYMMDDXXC, whereas + *
+ * See Hungarian identification number
+ */
+public class HungarianIdNumber implements IdNumberGenerator {
+
+ private static final DateTimeFormatter BIRTHDAY_FORMAT = DateTimeFormatter.ofPattern("yyMMdd");
+
+ @Override
+ public String countryCode() {
+ return "HU";
+ }
+
+ @Override
+ public String generateInvalid(BaseProviders faker) {
+ String validIdNumber = generateValid(faker);
+ String basePart = validIdNumber.substring(0, 9);
+ int validCheckDigit = getNumericValue(validIdNumber.charAt(9));
+ int invalidCheckDigit = (validCheckDigit + 1) % 10;
+ return basePart + invalidCheckDigit;
+ }
+
+ @Override
+ public PersonIdNumber generateValid(BaseProviders faker, IdNumber.IdNumberRequest request) {
+ LocalDate birthday = faker.timeAndDate().birthday();
+ PersonIdNumber.Gender gender = randomGender(faker);
+ int checkDigit;
+ String basePart;
+ do {
+ basePart = basePart(faker, birthday, gender);
+ checkDigit = getCheckDigit(basePart);
+ } while (checkDigit == 10);
+
+ String idNumber = basePart + checkDigit;
+ return new PersonIdNumber(idNumber, birthday, gender);
+ }
+
+ private String basePart(BaseProviders faker, LocalDate birthday, PersonIdNumber.Gender gender) {
+ return firstDigit(birthday.getYear(), gender) +
+ BIRTHDAY_FORMAT.format(birthday) +
+ faker.number().digits(2);
+ }
+
+ static int getCheckDigit(String basePart) {
+ char[] numbers = basePart.toCharArray();
+ int summ = 0;
+ for (int i = 0; i < numbers.length; i++) {
+ summ += getNumericValue(numbers[i]) * (i + 1);
+ }
+
+ return summ % 11;
+ }
+
+ static int firstDigit(int birthYear, PersonIdNumber.Gender gender) {
+ return switch (gender) {
+ case MALE -> isInRange(birthYear) ? 1 : 3;
+ case FEMALE -> isInRange(birthYear) ? 2 : 4;
+ };
+ }
+
+ private static boolean isInRange(int birthYear) {
+ return birthYear >= 1900 && birthYear <= 1999;
+ }
+
+}
diff --git a/src/main/resources/META-INF/services/net.datafaker.idnumbers.IdNumberGenerator b/src/main/resources/META-INF/services/net.datafaker.idnumbers.IdNumberGenerator
index 3633ebdda..36f31788d 100644
--- a/src/main/resources/META-INF/services/net.datafaker.idnumbers.IdNumberGenerator
+++ b/src/main/resources/META-INF/services/net.datafaker.idnumbers.IdNumberGenerator
@@ -5,6 +5,7 @@ net.datafaker.idnumbers.ChineseIdNumber
net.datafaker.idnumbers.EstonianIdNumber
net.datafaker.idnumbers.FrenchIdNumber
net.datafaker.idnumbers.GeorgianIdNumber
+net.datafaker.idnumbers.HungarianIdNumber
net.datafaker.idnumbers.ItalianIdNumber
net.datafaker.idnumbers.LatvianIdNumber
net.datafaker.idnumbers.MacedonianIdNumber
diff --git a/src/test/java/net/datafaker/helpers/IdNumberPatterns.java b/src/test/java/net/datafaker/helpers/IdNumberPatterns.java
index cc069dbee..3248f8b38 100644
--- a/src/test/java/net/datafaker/helpers/IdNumberPatterns.java
+++ b/src/test/java/net/datafaker/helpers/IdNumberPatterns.java
@@ -10,5 +10,6 @@ public class IdNumberPatterns {
public static final Pattern FRENCH = Pattern.compile("[12]\\d{2}(1[0-2]|0[1-9])\\d[0-9a-zA-Z]\\d{8}");
public static final Pattern ITALIAN = Pattern.compile("[A-Z]{6}\\d{2}[ABCDEHLMPRST]\\d{2}[\\dA-Z]{5}");
public static final Pattern POLISH = Pattern.compile("\\d{11}");
+ public static final Pattern HUNGARIAN = Pattern.compile("[1-4]\\d{9}");
}
diff --git a/src/test/java/net/datafaker/idnumbers/HungarianIdNumberTest.java b/src/test/java/net/datafaker/idnumbers/HungarianIdNumberTest.java
new file mode 100644
index 000000000..16a792fa7
--- /dev/null
+++ b/src/test/java/net/datafaker/idnumbers/HungarianIdNumberTest.java
@@ -0,0 +1,34 @@
+package net.datafaker.idnumbers;
+
+import org.junit.jupiter.api.Test;
+
+import static net.datafaker.providers.base.PersonIdNumber.Gender.FEMALE;
+import static net.datafaker.providers.base.PersonIdNumber.Gender.MALE;
+import static org.assertj.core.api.Assertions.assertThat;
+
+class HungarianIdNumberTest {
+
+ @Test
+ void firstDigit() {
+ assertThat(HungarianIdNumber.firstDigit(1899, MALE)).isEqualTo(3);
+ assertThat(HungarianIdNumber.firstDigit(1900, MALE)).isEqualTo(1);
+ assertThat(HungarianIdNumber.firstDigit(1901, MALE)).isEqualTo(1);
+ assertThat(HungarianIdNumber.firstDigit(1899, FEMALE)).isEqualTo(4);
+ assertThat(HungarianIdNumber.firstDigit(1900, FEMALE)).isEqualTo(2);
+ assertThat(HungarianIdNumber.firstDigit(1901, FEMALE)).isEqualTo(2);
+ assertThat(HungarianIdNumber.firstDigit(1999, MALE)).isEqualTo(1);
+ assertThat(HungarianIdNumber.firstDigit(2000, MALE)).isEqualTo(3);
+ assertThat(HungarianIdNumber.firstDigit(1999, FEMALE)).isEqualTo(2);
+ assertThat(HungarianIdNumber.firstDigit(2000, FEMALE)).isEqualTo(4);
+ }
+
+ @Test
+ void checkDigit() {
+ assertThat(HungarianIdNumber.getCheckDigit("807159215")).isEqualTo(3);
+ assertThat(HungarianIdNumber.getCheckDigit("100000000")).isEqualTo(1);
+ assertThat(HungarianIdNumber.getCheckDigit("010000000")).isEqualTo(2);
+ assertThat(HungarianIdNumber.getCheckDigit("001000000")).isEqualTo(3);
+ assertThat(HungarianIdNumber.getCheckDigit("000000001")).isEqualTo(9);
+ assertThat(HungarianIdNumber.getCheckDigit("170010103")).isEqualTo(10);
+ }
+}
diff --git a/src/test/java/net/datafaker/providers/base/IdNumberTest.java b/src/test/java/net/datafaker/providers/base/IdNumberTest.java
index 020d79bf4..e011479a7 100644
--- a/src/test/java/net/datafaker/providers/base/IdNumberTest.java
+++ b/src/test/java/net/datafaker/providers/base/IdNumberTest.java
@@ -34,6 +34,7 @@ class IdNumberTest extends BaseFakerTest