我希望创建一个确定性数字生成函数,其中输入的数字总是生成相同的数字,但没有两个数字最终生成相同的结果.

例如.:

1 -> 3
2 -> 5
3 -> 4
4 -> 2
5 -> 1

然而,我需要它来处理所有可以由特定数据类型表示的数字,例如int64.

这感觉应该是非常简单的,或者完全不可能的.是否有某种随机数生成方案可以保证这种分布,而无需我创建一个包含所有可能数的数组,随机排序,然后使用索引(同时让我耗尽内存)?

非常感谢

推荐答案

您需要的转换公式是:

f(P) = (mP + s) mod n

// n = range - so for uint64 2^64
// s < range i.e. < 2^64
// m = must be coprime with n

这是Affine cipher中使用的modular arithmetic.

mod确保它在期望的范围内,s是一个简单的移位,m应该是coprimen.

所以对于uint64范围:

var (
    m = uint64(39293)    // some non-even number
    s = uint64(75321908) // some random number below 2^64
)

func transform(p uint64) uint64 {
    return p*m + s // implicitly mod'ed 2^64 by the type's size
}

这可能看起来很神奇,但你可以说服自己它适用于uint16:

https://go.dev/play/p/EKB6SH3-SGu

因为uint64将需要相当多的资源来运行:-)

Go相关问答推荐

Go GORM创建表,但不创建列

如何在jsonrpc服务器的服务器端捕获错误?

租户GUID X的租户不存在self 邮箱帐户的租户(我是唯一的成员)

使用Go使用Gorm使用外键对数据进行排序

通过渠道和goroutines增值1000倍

无法使用exec从管道中读取.Go中的命令

使用Dockertest进行Golang SQL单元测试的基本设置

使用Go和Operator SDK通过API调用设置Kubernetes Pods的安装步骤

这是实现超时的常见方法,为什么 time.After 不起作用

如何用mpb创建两行进度条?

同一文件上的多个 Arrow CSV 阅读器返回 null

错误!在为 age-viewer-go 运行 wails dev 或 wails build 命令时

Gremlin-Go:树步骤不可序列化

go:识别重新定义标志的包

go 是否对 struct 使用空间填充之类的东西?

分配空切片而不引用其类型?

如何从 Go 1.18 中的单个方法返回两种不同的具体类型?

使用正则表达式拆分具有相同标题的数据块

如何将类型转换为字节数组golang

如果在调用 http.Get(url) 时发生错误,我们是否需要关闭响应对象?