Skip to content

Instantly share code, notes, and snippets.

@ElianFabian
Created July 12, 2024 17:06
Show Gist options
  • Select an option

  • Save ElianFabian/44e463224c4bb67c81f57ca20277d35f to your computer and use it in GitHub Desktop.

Select an option

Save ElianFabian/44e463224c4bb67c81f57ca20277d35f to your computer and use it in GitHub Desktop.
Set seed of XorWowRandom in Kotlin.
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