Coverage Summary for Class: InnIndividualGenerator (ru.eda.plgn.bizgen.core.generator.impl)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| InnIndividualGenerator |
100%
(1/1)
|
100%
(2/2)
|
|
100%
(3/3)
|
100%
(13/13)
|
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
import kotlin.random.Random
/**
* ИНН Генератор для ФЛ.
*
* **See Also:**
* [Идентификационный номер налогоплательщика](https://ru.wikipedia.org/wiki/%D0%98%D0%B4%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BD%D0%BE%D0%BC%D0%B5%D1%80_%D0%BD%D0%B0%D0%BB%D0%BE%D0%B3%D0%BE%D0%BF%D0%BB%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%89%D0%B8%D0%BA%D0%B0)
*/
class InnIndividualGenerator : GeneratorStr {
override val uniqueDistance: Int = 130
override fun generate(): GeneratorResult<String> = GeneratorResultWithEscape(data = InnGeneratorBase.randomIndividualInn())
}
/**
* ИНН Генератор для ЮЛ.
*
* **See Also:**
* [Идентификационный номер налогоплательщика](https://ru.wikipedia.org/wiki/%D0%98%D0%B4%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BD%D0%BE%D0%BC%D0%B5%D1%80_%D0%BD%D0%B0%D0%BB%D0%BE%D0%B3%D0%BE%D0%BF%D0%BB%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%89%D0%B8%D0%BA%D0%B0)
*/
class InnLegalGenerator : GeneratorStr {
override val uniqueDistance: Int = 130
override fun generate(): GeneratorResult<String> = GeneratorResultWithEscape(data = InnGeneratorBase.randomLegalInn())
}
/**
* Базовая реализация ИНН Генератора.
*
* @author Dmitry_Emelyanenko
*/
private object InnGeneratorBase {
private const val MIN_REGION = 1
private const val MAX_REGION = 99
private val P10 = intArrayOf(2, 4, 10, 3, 5, 9, 4, 6, 8)
private val P11 = intArrayOf(7, 2, 4, 10, 3, 5, 9, 4, 6, 8)
private val P12 = intArrayOf(3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8)
private enum class InnType {
LEGAL,
INDIVIDUAL
}
/** ИНН ЮЛ. */
fun randomLegalInn(): String = generateInn(InnType.LEGAL)
/** ИНН ФЛ. */
fun randomIndividualInn(): String = generateInn(InnType.INDIVIDUAL)
private fun generateInn(type: InnType): String {
val random = Random.Default
val region = generateRegion(random)
val sequence = generateSequence(type, random)
val baseInn = region + sequence
return baseInn + calculateCheckDigits(baseInn)
}
private fun generateRegion(random: Random): String {
return random.nextInt(MIN_REGION, MAX_REGION).toString().padStart(2, '0')
}
private fun generateSequence(type: InnType, random: Random): String {
return when (type) {
InnType.LEGAL -> random.nextInt(1_000_000, 10_000_000).toString()
InnType.INDIVIDUAL -> random.nextInt(10_000_000, 100_000_000).toString()
}
}
private fun calculateCheckDigits(baseInn: String): String {
return when (baseInn.length) {
9 -> calculateCheckDigit(P10, baseInn)
10 -> {
val firstDigit = calculateCheckDigit(P11, baseInn)
val secondDigit = calculateCheckDigit(P12, baseInn + firstDigit)
firstDigit + secondDigit
}
else -> throw IllegalArgumentException("Invalid base INN length: ${baseInn.length}. Available values: 9 or 10")
}
}
private fun calculateCheckDigit(weights: IntArray, digits: String): String {
require(digits.length == weights.size) { "Digits length must match weights size" }
val sum = digits.foldIndexed(0) { index, acc, c ->
acc + weights[index] * (c - '0')
}
return ((sum % 11) % 10).toString()
}
}