ios Swift:寻找具有相同输出的Java的Random()PRNG的交叉兼容方法

这是我的delimna:我正在编写一个应用程序,需要从Java编写的游戏中精确地再现PRNG输出,该游戏使用Java random()和给定的种子来创建它的所有初始游戏“世界”数据。

我面临的问题是Java的random()和ios Swift原生PRNG在给出完全相同的种子时不会生成相同的值。

以下是我的测试用例:在所有情况下都使用相同的“种子”,公式用于0到9之间的随机整数。

在Java中:

import java.util.Random; long seed = 987234904; Random rnd = new Random(seed); int result = rnd.nextInt(10); 

Java random()’result’= 0

在ios Swift中 – 使用srand48()/ drand48():

 import UIKit var seed: Int = 987234904 srand48(seed) var result = Int(drand48()*10) 

ios Swift drand48()’result’= 7

在ios Swift中 – 使用rand_r():

 import UIKit var seed: UInt32 = 987234904 var result = Int(Float(rand_r(&seed))/Float(INT32_MAX)*10) 

ios Swift rand_r()结果= 4

考虑到这一点 – 是否有一个ios Swift | Objective-C | C ++代码snippit |库在function和输出方面与Java的random()版本完全相同?

不,这是不可能的(最有可能),因为随机的实现甚至不需要通过不同的版本和系统保持不变,您必须实现自己的随机算法以确保。 或者你可以生成一个序列,保存它并以某种方式将其传输到另一个设备,但这更加复杂。

请查看此链接中的EXAMPLE部分, 该部分提供了一种算法,并指出这可能对两台不同的机器有用:

 static unsigned long next = 1; /* RAND_MAX assumed to be 32767 */ int myrand(void) { next = next * 1103515245 + 12345; return((unsigned)(next/65536) % 32768); } void mysrand(unsigned seed) { next = seed; } 

您只需将其翻译为首选语言即可

在iOS 9和OS X 10.11中, GameplayKit提供了一套确定性PRNG – 主要原理之一是,您可以跨多个设备或服务器和客户端之间复制随机序列以进行多人游戏。 (有关更多理由和其他有趣内容,请参阅WWDC会议 。)

特别是, GKLinearCongruentialRandomSource使用Knuth标准,因此应与java.util.Random兼容(当然,当用相同的48位种子初始化时)。

好的 – 这是解决方案:

我在Apple论坛上问了同样的问题,并且通过’ahltorp’共享交流function处理了一个好人,他们一直在使用它们。 它是快速兼容的,我已经测试了它对我的模拟,它是一个完美的数据匹配!

C函数的Github位置: https : //github.com/ahltorp/swiftjavarandom

Swift示例使用它

 var inseed: UInt64 = 987234904 java_random_setseed(&inseed, inseed) var result = java_random_nextint_n(&inseed, 10) print(result) 

结果= 0 🙂

链接到苹果论坛讨论: https : //forums.developer.apple.com/thread/5791?q = Swift%20prng