Created
July 12, 2024 17:06
-
-
Save ElianFabian/44e463224c4bb67c81f57ca20277d35f to your computer and use it in GitHub Desktop.
Set seed of XorWowRandom in Kotlin.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import kotlin.random.Random | |
| import kotlin.reflect.full.declaredMemberProperties | |
| import kotlin.reflect.jvm.isAccessible | |
| fun main() { | |
| val random = Random(42) | |
| println(random.nextInt()) | |
| println(random.nextInt()) | |
| println(random.nextInt()) | |
| println(random.nextInt()) | |
| random.setSeed(42) | |
| println(random.nextInt()) | |
| println(random.nextInt()) | |
| println(random.nextInt()) | |
| println(random.nextInt()) | |
| } | |
| fun Random.setSeed(seed: Int) { | |
| if (this::class.qualifiedName != "kotlin.random.XorWowRandom") { | |
| throw IllegalArgumentException("This method only works with XorWowRandom") | |
| } | |
| val seed1 = seed | |
| val seed2 = seed.shr(31) | |
| this::class.declaredMemberProperties.forEach { prop -> | |
| prop.isAccessible = true | |
| when (prop.name) { | |
| "x" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, seed1) | |
| "y" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, seed2) | |
| "z" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, 0) | |
| "w" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, 0) | |
| "v" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, seed1.inv()) | |
| "addend" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, (seed1 shl 10) xor (seed2 ushr 4)) | |
| } | |
| } | |
| // Discard first 64 values as done in the original constructor | |
| repeat(64) { this.nextInt() } | |
| } | |
| fun Random.setSeed(seed: Long) { | |
| if (this::class.qualifiedName != "kotlin.random.XorWowRandom") { | |
| throw IllegalArgumentException("This method only works with XorWowRandom") | |
| } | |
| val seed1 = seed.toInt() | |
| val seed2 = seed.shr(32).toInt() | |
| this::class.declaredMemberProperties.forEach { prop -> | |
| prop.isAccessible = true | |
| when (prop.name) { | |
| "x" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, seed1) | |
| "y" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, seed2) | |
| "z" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, 0) | |
| "w" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, 0) | |
| "v" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, seed1.inv()) | |
| "addend" -> (prop as kotlin.reflect.KMutableProperty<*>).setter.call(this, (seed1 shl 10) xor (seed2 ushr 4)) | |
| } | |
| } | |
| // Discard first 64 values as done in the original constructor | |
| repeat(64) { this.nextInt() } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment