Coverage Summary for Class: SnilsGenerator (ru.eda.plgn.bizgen.core.generator.impl)

Class Method, % Branch, % Line, % Instruction, %
SnilsGenerator 100% (3/3) 100% (4/4) 100% (64/64)
SnilsGenerator$Companion 100% (2/2) 83.3% (5/6) 100% (7/7) 98.7% (149/151)
Total 100% (5/5) 83.3% (5/6) 100% (11/11) 99.1% (213/215)


 package ru.eda.plgn.bizgen.core.generator.impl
 
 import ru.eda.plgn.bizgen.core.generator.GeneratorResult
 import ru.eda.plgn.bizgen.core.generator.GeneratorResultWithEscape
 import ru.eda.plgn.bizgen.core.generator.GeneratorStr
 
 /**
  * Страховой номер индивидуального лицевого счёта (СНИЛС).
  *
  * Формат СНИЛС: «***ХХХ-ХХХ-ХХХ YY***»,
  *
  * где X, Y — цифры, причём первые девять цифр 'X' — это любые цифры, а последние две 'Y' фактически являются контрольной суммой.
  *
  * Алгоритм формирования контрольного числа СНИЛС таков:
  * - Каждая цифра СНИЛС умножается на номер своей позиции (позиции отсчитываются с конца, то есть, справа)
  * - Полученные произведения суммируются
  * - Получить остаток от деления на 101
  * - Если получилось 100, контрольное число равно 0
  *
  * *Например:*
  *
  * *СНИЛС 112-233-445 95. Проверяем правильность контрольного числа:*
  * - *цифры номера 1 1 2 2 3 3 4 4 5*
  * - *номер позиции 9 8 7 6 5 4 3 2 1*
  * - *Сумма = 1 ⋅ 9 + 1 ⋅ 8 + 2 ⋅ 7 + 2 ⋅ 6 + 3 ⋅ 5 + 3 ⋅ 4 + 4 ⋅ 3 + 4 ⋅ 2 + 5 ⋅ 1 = 95*
  * - *Контрольная сумма = 95 mod 101 = 95. Полученное значение совпадает с представленной контрольнной суммой*
  *
  * **See Also:**
  * [СНИЛС](https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D1%80%D0%B0%D1%85%D0%BE%D0%B2%D0%BE%D0%B9_%D0%BD%D0%BE%D0%BC%D0%B5%D1%80_%D0%B8%D0%BD%D0%B4%D0%B8%D0%B2%D0%B8%D0%B4%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BB%D0%B8%D1%86%D0%B5%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D1%87%D1%91%D1%82%D0%B0)
  *
  * @author Dmitry_Emelyanenko
  */
 class SnilsGenerator : GeneratorStr {
   override val uniqueDistance: Int = 130
 
   override fun generate(): GeneratorResult<String> = GeneratorResultWithEscape(randomSNILS())
 
   private companion object {
     val COEFFICIENTS = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
 
     fun randomSNILS(): String {
       val data = List(COEFFICIENTS.size) { (1..9).random() }
 
       val checkDigit = data.zip(COEFFICIENTS)
         .sumOf { (d, c) -> d * c }
         .mod(101)
         .let { if (it == 100) 0 else it }
 
       return "${data[8]}${data[7]}${data[6]}-${data[5]}${data[4]}${data[3]}-${data[2]}${data[1]}${data[0]} " + "%02d".format(checkDigit)
     }
   }
 }