// ĠSPDX - File Copyright Text : Ġ 2 0 1 9 , ĠAnd ras ĠVer es - Sz ent k ia aly i Ġ< vs za @ vs za . hu > Ċ // ĠSPDX - License - Identifier : ĠMIT Ċ Ċ package Ġorg . hs bp . andro sphinx Ċ Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . Byte Order Ċ import Ġjava . util .* Ċ import Ġkotlin . experimental . and Ċ import Ġkotlin . experimental . or Ċ import Ġkotlin . math . log Ċ Ċ enum Ġclass ĠCharacter Class ( private Ġval Ġbit : ĠByte , Ġinternal Ġval Ġrange : ĠSet < Char >, Ġval Ġdescription : ĠInt ) Ġ{ ĊĠĠĠ ĠUPPER ( bit Ġ= Ġ 1 , Ġrange Ġ= ĠChar Range (' A ', Ġ' Z '). toSet (), Ġdescription Ġ= ĠR . string . character _ class _ upper ), ĊĠĠĠ ĠLOWER ( bit Ġ= Ġ 2 , Ġrange Ġ= ĠChar Range (' a ', Ġ' z '). toSet (), Ġdescription Ġ= ĠR . string . character _ class _ lower ), ĊĠĠĠ ĠSYMBOL S ( bit Ġ= Ġ 4 , Ġrange Ġ= ĠChar Range (' Ġ', Ġ'/') Ġunion ĠChar Range (' :', Ġ'@ ') Ġunion ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChar Range ('[ ', Ġ'` ') Ġunion ĠChar Range ('{ ', Ġ'~ '), Ġdescription Ġ= ĠR . string . character _ class _ symbols ), ĊĠĠĠ ĠDIG ITS ( bit Ġ= Ġ 8 , Ġrange Ġ= ĠChar Range (' 0 ', Ġ' 9 '). toSet (), Ġdescription Ġ= ĠR . string . character _ class _ digits ); ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġserialize ( values : ĠSet < Character Class >): ĠByte Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġvalues . fold ( 0 . to Byte ()) Ġ{ Ġacc , Ġcc Ġ-> Ġacc Ġor Ġcc . bit Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġparse ( serialized : ĠByte ): ĠSet < Character Class > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues (). filter To ( Enum Set . none Of ( Character Class :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . bit Ġand Ġserialized Ġ== Ġit . bit Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġderive ( r wd : ĠByteArray , Ġrule : ĠSet < Character Class >, Ġsize : ĠInt ): ĠChar Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( rule . isNotEmpty ()) Ġ{ Ġ" At Ġleast Ġone Ġcharacter Ġclass Ġmust Ġbe Ġallowed ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġorder Ġ= ĠarrayOf ( SYMBOL S , ĠUPPER , ĠLOWER , ĠDIG ITS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchars Ġ= Ġorder . filter ( rule :: contains ). flatMap Ġ{ Ġit . range . sorted () Ġ}. toList () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpassword Ġ= Ġencode ( r wd , Ġchars ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( size Ġ> Ġ 0 ) Ġsub Array With Clean ing ( password , Ġsize ) Ġelse Ġpassword ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġencode ( raw : ĠByteArray , Ġchars : ĠList < Char >): ĠChar Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl Ġ= Ġraw . size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġr Ġ= Ġl . rem ( 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinput Ġ= Ġif Ġ( r Ġ== Ġ 0 ) Ġraw Ġelse Ġraw Ġ+ ĠByteArray ( r ) Ġ{ Ġ 0 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġib Ġ= ĠByteBuffer . wrap ( input ). order ( Byte Order . BIG _ ENDIAN ). as Int Buffer () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchar Size Ġ= Ġchars . size . to Long () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġout Fact Ġ= Ġlog ( 0 x 1 0 0 0 0 0 0 0 0 . toDouble (), Ġchar Size . toDouble ()). toInt () Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠChar Array ( out Fact Ġ* Ġib . capacity ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġindex Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( ib . has Remaining ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġword Ġ= Ġib . get (). to Long () Ġand Ġ 0 xFFFFFFFF ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrepeat ( out Fact ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout [ index ++] Ġ= Ġchars [ word . rem ( char Size ). toInt ()] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġword Ġ/= Ġchar Size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġo len Ġ= Ġ( if Ġ( r Ġ== Ġ 0 ) Ġ 0 Ġelse Ġr Ġ+ Ġ 1 ) Ġ+ Ġl Ġ/ Ġ 4 Ġ* Ġout Fact ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsub Array With Clean ing ( out , Ġo len ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġsub Array With Clean ing ( input : ĠChar Array , Ġsize : ĠInt ): ĠChar Array Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( input . size Ġ== Ġsize ) Ġreturn Ġinput ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġinput . slice Array ( 0 Ġuntil Ġsize ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . fill ('\ u 0 0 0 0 ') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ