@@ -9,72 +9,72 @@ import kotlinx.io.*
9
9
import kotlin.test.Test
10
10
import kotlin.test.assertEquals
11
11
12
- /* *
13
- * Source decrypting all the data read from the downstream using RC4 algorithm.
14
- *
15
- * See https://en.wikipedia.org/wiki/RC4 for more information about the cypher.
16
- *
17
- * Implementation of RC4 stream cypher based on http://cypherpunks.venona.com/archive/1994/09/msg00304.html
18
- */
19
- @OptIn(ExperimentalUnsignedTypes ::class )
20
- class RC4DecryptingSource (private val downstream : RawSource , key : String ): RawSource {
21
- private val buffer = Buffer ()
22
- private val key = RC4Key (key)
12
+ class RC4SourceSample {
13
+ @Test
14
+ fun rc4 () {
15
+ /* *
16
+ * Source decrypting all the data read from the downstream using RC4 algorithm.
17
+ *
18
+ * See https://en.wikipedia.org/wiki/RC4 for more information about the cypher.
19
+ *
20
+ * Implementation of RC4 stream cypher based on http://cypherpunks.venona.com/archive/1994/09/msg00304.html
21
+ */
22
+ @OptIn(ExperimentalUnsignedTypes ::class )
23
+ class RC4DecryptingSource (private val downstream : RawSource , key : String ): RawSource {
24
+ private val buffer = Buffer ()
25
+ private val key = RC4Key (key)
23
26
24
- override fun readAtMostTo (sink : Buffer , byteCount : Long ): Long {
25
- val bytesRead = downstream.readAtMostTo(buffer, byteCount)
26
- if (bytesRead == - 1L ) {
27
- return - 1L
28
- }
27
+ override fun readAtMostTo (sink : Buffer , byteCount : Long ): Long {
28
+ val bytesRead = downstream.readAtMostTo(buffer, byteCount)
29
+ if (bytesRead == - 1L ) {
30
+ return - 1L
31
+ }
29
32
30
- while (! buffer.exhausted()) {
31
- val byte = buffer.readByte()
32
- sink.writeByte(byte.xor(key.nextByte()))
33
- }
33
+ while (! buffer.exhausted()) {
34
+ val byte = buffer.readByte()
35
+ sink.writeByte(byte.xor(key.nextByte()))
36
+ }
34
37
35
- return bytesRead
36
- }
38
+ return bytesRead
39
+ }
37
40
38
- override fun close () = downstream.close()
41
+ override fun close () = downstream.close()
39
42
40
- private class RC4Key (key : String ) {
41
- private var keyState: UByteArray
42
- private var keyX: Int = 0
43
- private var keyY: Int = 0
43
+ private inner class RC4Key (key : String ) {
44
+ private var keyState: UByteArray
45
+ private var keyX: Int = 0
46
+ private var keyY: Int = 0
44
47
45
- init {
46
- require(key.isNotEmpty()) { " Key could not be empty" }
47
- val keyBytes = key.encodeToByteArray()
48
- keyState = UByteArray (256 ) { it.toUByte() }
49
- var index1 = 0
50
- var index2 = 0
48
+ init {
49
+ require(key.isNotEmpty()) { " Key could not be empty" }
50
+ val keyBytes = key.encodeToByteArray()
51
+ keyState = UByteArray (256 ) { it.toUByte() }
52
+ var index1 = 0
53
+ var index2 = 0
51
54
52
- for (idx in keyState.indices) {
53
- index2 = (keyBytes[index1] + keyState[idx].toInt() + index2) % 256
54
- swapStateBytes(idx, index2)
55
- index1 = (index1 + 1 ) % keyBytes.size
56
- }
57
- }
55
+ for (idx in keyState.indices) {
56
+ index2 = (keyBytes[index1] + keyState[idx].toInt() + index2) % 256
57
+ swapStateBytes(idx, index2)
58
+ index1 = (index1 + 1 ) % keyBytes.size
59
+ }
60
+ }
58
61
59
- fun nextByte (): Byte {
60
- keyX = (keyX + 1 ) % 256
61
- keyY = (keyState[keyX].toInt() + keyY) % 256
62
- swapStateBytes(keyX, keyY)
63
- val idx = (keyState[keyX] + keyState[keyY]) % 256U
64
- return keyState[idx.toInt()].toByte()
65
- }
62
+ fun nextByte (): Byte {
63
+ keyX = (keyX + 1 ) % 256
64
+ keyY = (keyState[keyX].toInt() + keyY) % 256
65
+ swapStateBytes(keyX, keyY)
66
+ val idx = (keyState[keyX] + keyState[keyY]) % 256U
67
+ return keyState[idx.toInt()].toByte()
68
+ }
66
69
67
- private fun swapStateBytes (x : Int , y : Int ) {
68
- val tmp = keyState[x]
69
- keyState[x] = keyState[y]
70
- keyState[y] = tmp
70
+ private fun swapStateBytes (x : Int , y : Int ) {
71
+ val tmp = keyState[x]
72
+ keyState[x] = keyState[y]
73
+ keyState[y] = tmp
74
+ }
75
+ }
71
76
}
72
- }
73
- }
74
77
75
- class RC4SourceSample {
76
- @Test
77
- fun rc4 () {
78
78
val key = " key"
79
79
val source = Buffer ().also { it.write(byteArrayOf(0x58 , 0x09 , 0x57 , 0x9fU .toByte(), 0x41 , 0xfbU .toByte())) }
80
80
val rc4Source = RC4DecryptingSource (source, key).buffered()
0 commit comments