Skip to content

Commit 27d23a0

Browse files
committed
Implement Knuth–Morris–Pratt Algorithm
1 parent 72b63a1 commit 27d23a0

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,6 @@
6868
10. Post-order Deep First Search Traversal – [solution](src/main/kotlin/ru/romanow/algorithms/PostOrderDeepFirstSearch.kt), [test](src/test/kotlin/ru/romanow/algorithms/PostOrderDeepFirstSearchTest.kt)
6969
11. Breadth First Search Traversal – [solution](src/main/kotlin/ru/romanow/algorithms/BreadthFirstSearch.kt), [test](src/test/kotlin/ru/romanow/algorithms/BreadthFirstSearchTest.kt)
7070
12. Knuth–Morris–Pratt Algorithm – [solution](src/main/kotlin/ru/romanow/algorithms/KnuthMorrisPrattAlgorithm.kt), [test](src/test/kotlin/ru/romanow/algorithms/KnuthMorrisPrattAlgorithmTest.kt)
71+
13. Crc32 – [solution](src/main/kotlin/ru/romanow/algorithms/Crc32.kt), [test](src/test/kotlin/ru/romanow/algorithms/Crc32Test.kt)
7172

7273
[//]: # (@formatter:on)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package ru.romanow.algorithms
2+
3+
class Crc32 {
4+
fun compute(data: ByteArray): Int {
5+
// Стандартный полином CRC-32 IEEE 802.3: 0x04C11DB7
6+
val poly = 0x04C11DB7
7+
// Начальное значение CRC (все биты = 1)
8+
var crc = 0xFFFFFFFF.toInt()
9+
10+
// Обработка каждого байта входных данных
11+
for (byte in data) {
12+
// Преобразуем байт к Int и сдвигаем влево на 24 бита. Это нужно,
13+
// чтобы выставить обрабатываемый байт в старшие биты регистра CRC.
14+
var b = byte.toInt() shl 24
15+
// Обработка каждого бита текущего байта
16+
repeat(8) {
17+
// XOR старшего бита CRC и текущего бита байта. Если результат
18+
// имеет установленный старший бит, применяем полином.
19+
val bit = ((crc xor b) and 0x80000000.toInt()) != 0
20+
// Сдвигаем CRC влево на 1 бит
21+
crc = (crc shl 1) xor if (bit) poly else 0
22+
// Сдвигаем байт влево на 1 бит, чтобы перейти к следующему биту
23+
b = b shl 1
24+
}
25+
}
26+
// Инвертируем все биты в конце (финальный XOR), как требует стандарт CRC-32
27+
return crc.inv()
28+
}
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package ru.romanow.algorithms
2+
3+
import org.assertj.core.api.Assertions.assertThat
4+
import org.junit.jupiter.api.extension.ExtensionContext
5+
import org.junit.jupiter.params.ParameterizedTest
6+
import org.junit.jupiter.params.provider.Arguments
7+
import org.junit.jupiter.params.provider.ArgumentsProvider
8+
import org.junit.jupiter.params.provider.ArgumentsSource
9+
import java.util.stream.Stream
10+
import kotlin.text.HexFormat.Companion.UpperCase
11+
12+
class Crc32Test {
13+
14+
@OptIn(ExperimentalStdlibApi::class)
15+
@ArgumentsSource(ValueProvider::class)
16+
@ParameterizedTest(name = "#{index} – crc32 {0} is {1}")
17+
fun sort(data: String, expected: String) {
18+
val obj = Crc32()
19+
val result = obj.compute(data.toByteArray())
20+
assertThat(result.toHexString(UpperCase)).isEqualTo(expected)
21+
}
22+
23+
internal class ValueProvider : ArgumentsProvider {
24+
override fun provideArguments(context: ExtensionContext): Stream<Arguments> =
25+
Stream.of(
26+
Arguments.of("hello", "1931653D"),
27+
Arguments.of("test", "338BCFAC"),
28+
Arguments.of("twentysix", "C07BD465")
29+
)
30+
}
31+
}

0 commit comments

Comments
 (0)