@@ -3,35 +3,48 @@ import {
33 CodeLength ,
44 Strategy ,
55 CustomStrategyContext ,
6- CodeAnalysis ,
6+ HumanProfile ,
7+ SecurityMode ,
8+ RngProfile ,
9+ type CodeAnalysis ,
10+ type CodePrediction ,
711} from './types'
812import { getStrategyImpl } from './strategy'
913import { isCodeAllowed } from './validator'
1014import {
1115 getAllowedDigits ,
12- getRng ,
1316 fromDigits ,
1417 isAllSame ,
1518 isTooSimpleSequence ,
1619 pickDigit ,
1720 pickTwoDifferentDigits ,
1821 pickThreeDifferentDigits ,
22+ getRng ,
1923} from './utils'
24+ import { registerRng } from './rng'
25+ import { analyze } from './analyze'
26+ import { predictCodeQuality } from './predictor'
2027
21- export { analyze } from './analyze'
22-
23- export {
28+ export type {
2429 GenerateOptions ,
2530 CodeLength ,
26- Strategy ,
2731 CustomStrategyContext ,
32+ HumanProfile ,
33+ SecurityMode ,
34+ RngProfile ,
2835 CodeAnalysis ,
36+ CodePrediction ,
2937}
38+ export { Strategy , analyze , predictCodeQuality , registerRng }
3039
3140export function generateCode ( options : GenerateOptions = { } ) : string {
3241 const length : CodeLength = options . length === 4 ? 4 : 6
3342 const strategy : Strategy = options . strategy ?? Strategy . Mixed
3443
44+ if ( options . mode === 'banking' ) {
45+ return generateBankingCode ( { ...options , length } )
46+ }
47+
3548 const impl = getStrategyImpl ( length , strategy , options )
3649
3750 const maxAttempts = 100
@@ -50,6 +63,32 @@ export function generateCode(options: GenerateOptions = {}): string {
5063 return code . slice ( 0 , length )
5164}
5265
66+ function generateBankingCode ( options : GenerateOptions = { } ) : string {
67+ const length : CodeLength = options . length === 4 ? 4 : 6
68+ const digits = getAllowedDigits ( options )
69+ const rng = getRng ( { ...options , mode : 'banking' } )
70+
71+ const maxAttempts = 100
72+ for ( let i = 0 ; i < maxAttempts ; i ++ ) {
73+ const result : string [ ] = [ ]
74+ while ( result . length < length ) {
75+ const d = pickDigit ( digits , rng )
76+ if ( ! result . includes ( d ) ) {
77+ result . push ( d )
78+ }
79+ }
80+ const code = fromDigits ( result )
81+ if ( isCodeAllowed ( code , { ...options , mode : 'banking' } ) ) {
82+ return code
83+ }
84+ }
85+
86+ const fallback = fromDigits (
87+ Array . from ( { length } , ( ) => pickDigit ( digits , rng ) )
88+ )
89+ return fallback . slice ( 0 , length )
90+ }
91+
5392export function isHumanFriendly (
5493 code : string ,
5594 options ?: GenerateOptions
0 commit comments