Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何使用字符串作为Golang中rand.Seed()函数的输入?_String_Go_Random_Seed_Random Seed - Fatal编程技术网

String 如何使用字符串作为Golang中rand.Seed()函数的输入?

String 如何使用字符串作为Golang中rand.Seed()函数的输入?,string,go,random,seed,random-seed,String,Go,Random,Seed,Random Seed,我想做什么: 基于字符串的内容(例如,a1b2c3d4e5),我想生成一组“可重复”的随机事件。在Golang中生成可重复的随机数很容易-您只需使用函数为随机数生成器添加特定数字的种子,然后就完成了 但是,该函数将int64作为参数。因此,我需要以某种方式将字符串转换为int64 我已经尝试过的: 我的第一个想法是使用base64对字符串进行编码,然后将字节序列转换为int64。然而,通过一些基本的测试,似乎只支持长度约为7的字符串。添加第8个字符后,数字保持不变 我想这里的基本问题是,可能的字

我想做什么:

基于字符串的内容(例如,
a1b2c3d4e5
),我想生成一组“可重复”的随机事件。在Golang中生成可重复的随机数很容易-您只需使用函数为随机数生成器添加特定数字的种子,然后就完成了

但是,该函数将int64作为参数。因此,我需要以某种方式将字符串转换为int64

我已经尝试过的:

我的第一个想法是使用base64对字符串进行编码,然后将字节序列转换为int64。然而,通过一些基本的测试,似乎只支持长度约为7的字符串。添加第8个字符后,数字保持不变

我想这里的基本问题是,可能的字符串值比可能的int64值多


那么某种散列函数呢?据我所知,大多数散列函数都返回一个字节序列;我需要某种返回int64的哈希函数。也许这种方法也被误导了?

使用哈希函数是一个好的方向。要生成适合
int64
的值,只需获取散列值的前8个字节

对于一个好的散列函数,散列结果的每个字节(或者更确切地说,每个位)都取决于所有的输入字节,因此前8个字节不会在特定的输入长度后被“卡住”

要将8个字节的片转换为
int64
值,可以使用包

例如:

digest := ... // calculate digest
seed := int64(binary.BigEndian.Uint64(digest[:8]))

切片摘要值
digest[:8]
也可以省略,因为
BigEndian.Uint64()
调用将只读取前8个字节。

字符串的散列将完成此操作

您可以使用:

  • 字符串的总和(返回16个字节)
  • 将前8个字节转换为uint64(忽略其余部分。但如果输入少于8个字节,则会崩溃)
示例代码():

印刷品:

2458341265858962012
792667671
注意:md5只是一个例子。您可以使用生成至少8个字节的任何哈希。例:。只需将
md5.New()
替换为
sha256.New()
(以及导入)。 您可以找到一个很好的哈希示例列表


还有一个大字是警告:这根本不涉及加密应用程序。我假设这是用户提供的种子(例如:游戏种子),用于非加密目的。

你可以试试。通过使用时间生成不同的种子,可以为生成随机事件提供不同的序列

package main

import (
    "bytes"
    "fmt"
    "math/rand"
    "time"
)

var r = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
func main() {
    fmt.Println(randomString(10))
}

func randomString(l int) string {

    var result bytes.Buffer
    var temp string
    for i := 0; i < l; {
        if string(randInt(65, 90)) != temp {
            temp = string(randInt(65, 90))
            result.WriteString(temp)
            i++
        }
    }
    return result.String()
}

func randInt(min int, max int) int {
    return min + r.Intn(max-min)
}
主程序包
进口(
“字节”
“fmt”
“数学/兰德”
“时间”
)
var r=rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
func main(){
格式打印项次(随机字符串(10))
}
func随机字符串(l int)字符串{
var结果字节。缓冲区
变量临时字符串
对于i:=0;i
出于安全原因,是否要求种子不易从输入字符串中操作/检测?因为如果不是的话,我想不出任何理由为什么仅仅对字符串进行任何哈希并应用
mod MAXINT
是不够的。CRC64不是比MD5(或SHA256)更好的哈希算法吗,因为它只输出64位,因此不必忽略/截断任何内容?这肯定会起作用。如果这是一个游戏的随机数生成器,这将是完美的。然而,如果这是为了加密目的而为随机数生成器播种,那么sha256可能是迄今为止提到的三种方法中最好的一种。这是为了一个游戏。你能在CRC64的例子中编辑吗?CRC64使用起来有点烦人。您可以在我添加到答案的链接中看到示例(以及Go中的许多其他哈希)。
package main

import (
    "bytes"
    "fmt"
    "math/rand"
    "time"
)

var r = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
func main() {
    fmt.Println(randomString(10))
}

func randomString(l int) string {

    var result bytes.Buffer
    var temp string
    for i := 0; i < l; {
        if string(randInt(65, 90)) != temp {
            temp = string(randInt(65, 90))
            result.WriteString(temp)
            i++
        }
    }
    return result.String()
}

func randInt(min int, max int) int {
    return min + r.Intn(max-min)
}