Coverage Summary for Class: BankAccountGenerator (ru.eda.plgn.bizgen.core.generator.impl)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| BankAccountGenerator |
100%
(2/2)
|
|
100%
(3/3)
|
100%
(15/15)
|
| BankAccountGenerator$Companion |
100%
(2/2)
|
50%
(4/8)
|
94.1%
(16/17)
|
98.1%
(205/209)
|
| Total |
100%
(4/4)
|
50%
(4/8)
|
95%
(19/20)
|
98.2%
(220/224)
|
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 ru.eda.plgn.bizgen.core.generator.impl.BikGenerator.Companion.randomBik
import kotlin.random.Random
/**
* Корреспондентский счёт Генератор.
*
* *Генерирует корреспондентский счет банка на основе БИК.*
*
* *Формат: 30101810KXXXXX000NNN (20 цифр)*
* - *30101810 — префикс коррсчёта*
* - *K - контрольное число*
* - *XXXXX — последние 5 цифр БИК (кроме контрольных)*
* - *000 - фиксированные нули*
* - *NNN — условный номер (случайные цифры)*
*
* **See Also:**
* [Корреспондентский счёт](https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D1%80%D1%80%D0%B5%D1%81%D0%BF%D0%BE%D0%BD%D0%B4%D0%B5%D0%BD%D1%82%D1%81%D0%BA%D0%B8%D0%B9_%D1%81%D1%87%D1%91%D1%82)
*
* @author Dmitry_Emelyanenko
*/
class BankAccountGenerator : GeneratorStr {
override val uniqueDistance: Int = 130
override fun generate(): GeneratorResult<String> = GeneratorResultWithEscape(data = randomCorrespondentAccount(randomBik()))
/** Логика формирования корреспондентского счета. */
companion object {
/**
* Генерирует корреспондентский счет банка на основе БИК.
*
* Формат: 30101810KXXXXX000NNN (20 цифр)
* - 30101810 — префикс коррсчёта
* - K - контрольное число
* - XXXXX — последние 5 цифр БИК (кроме контрольных)
* - 000 - фиксированные нули
* - NNN — условный номер (случайные цифры)
*
* @param bik банковский идентификационный код (9 цифр)
* @throws IllegalArgumentException если БИК некорректен
*/
fun randomCorrespondentAccount(bik: String): String {
require(bik.length == 9 && bik.all { it.isDigit() }) {
"БИК должен содержать ровно 9 цифр"
}
// 1. Префикс (8 цифр)
val prefix = "30101810"
// 2. 5 цифр из БИК (позиции 5-9)
val bikPart = bik.substring(4, 9)
// 3. Фиксированные нули (3 цифры)
val fixedZeros = "000"
// 4. 3 случайные цифры
val randomSuffix = "%03d".format(Random.nextInt(1000))
// 5. Расчет контрольной цифры (на основе "0" + bikPart + fixedZeros + randomSuffix)
val baseForControl = "0$bikPart$fixedZeros$randomSuffix"
val controlDigit = calculateControlDigit(baseForControl)
// 6. Сборка счета (8 + 1 + 5 + 3 + 3 = 20 цифр)
return "$prefix$controlDigit$bikPart$fixedZeros$randomSuffix".also {
require(it.length == 20) { "Должно быть 20 цифр, получено: ${it.length}" }
}
}
/** Алгоритм расчета контрольной цифры для коррсчета. */
private fun calculateControlDigit(accountNumber: String): Int {
val weights = intArrayOf(7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1)
var sum = 0
accountNumber.forEachIndexed { index, char ->
sum += char.digitToInt() * weights[index]
}
return (sum % 10) * 3 % 10
}
}
}