如何在R中生成一个随机的64位十六进制数?

3
为了在区块链应用中使用,我需要在 R 中生成随机的 64 位十六进制数字。
考虑到计算机的容量限制,一次性获取这样一个 64 位十六进制数可能是相当繁琐的,甚至不可能实现。
因此,我想应该生成低位数的随机十六进制数,并将它们连接在一起以获得随机的 64 位十六进制数。
我已经接近解决方案:
library(fBasics)
.dec.to.hex(abs(ceiling(rnorm(1) * 1e6)))

生成随机十六进制数。问题在于有些情况下,我得到了6位十六进制数,而在其他情况下,我得到了7位十六进制数。因此,首要任务是解决这个问题。

有什么想法吗?


.dec.to.hex” 的文档在哪里可以找到?假设“dec”的缩写是“decimal”,这个函数的命名似乎有点奇怪:在 R 中,数字真的被存储为十进制吗?(或者它的作用是将十进制的字符串转换为十六进制?) - Mark Dickinson
1
也许不可能。当然不是不可能,但在R中拼写可能很麻烦。你似乎正在寻找R中类似Python的hex(random.getrandbits(256))的等效方式。是这样吗? - Mark Dickinson
@MarkDickinson fBasics::.dec.to.hex 揭示了它的内容:function (b) { ans = .chcode(b, base.in = 10, base.out = 16) ans } - Erdogan CEVHER
@MarkDickinson 我不懂Python,所以我无法对那个比较发表任何意见。 - Erdogan CEVHER
3个回答

8
你只需对每位数字进行采样,然后将它们拼接在一起即可。
set.seed(123)
paste0(sample(c(0:9, LETTERS[1:6]), 64, T), collapse = '')
## [1] "4C6EF08E87F7A91E305FEBAFAB8942FEBC07C353266522374D07C1832CE5A164"

非常优雅而简单! - Erdogan CEVHER
对于像我这样来到这里寻找如何生成唯一ID的人,这段代码非常适合插入for循环中:for (i in seq(nrow(database))){ database$uniqueID[i] <- paste0(sample(c(0:9, LETTERS), 64, T), collapse = '') }非常感谢。 - Pier-Eric Chamberland

1
.dec.to.hex()的最大参数是.dec.to.hex(2^30.99999....9)。 因此,问题简化为2^30.99999=2147468763是10的几次幂?

2147468763 = 2.147468763e9

1e9 < 2.147468763e9。因此是9次幂。但是,rnorm(1)可能会产生">5"。为了安全起见,使用8次幂(.dec.to.hex(abs(ceiling(rnorm(1) * 1e8)))是7或8个十六进制数字。10*7 >= 64)。

library(fBasics)
strtrim(paste(sapply(1:10, function(i) .dec.to.hex(abs(ceiling(rnorm(1) * 1e8)))), collapse=""), 64)
# 0397601803C22E220509810703BDE2300460EA80322F000CF50ABD0226F27009

只需要进行10次迭代而不是11次,因此操作稍微减少了一点!

nchar(strtrim(paste(sapply(1:10, function(i) .dec.to.hex(abs(ceiling(rnorm(1) * 1e8)))), collapse=""), 64))
# 64

2
这种方法不会给出均匀分布的十六进制字符串:某些长度为64的十六进制字符串比其他字符串更有可能出现。也许这正是你想要的,但如果你想要一个均匀分布,我建议使用runif(加上ceiling或floor)生成范围在[0, 2 ** 52)(每个都有13个十六进制数字)的整数。您只需要调用5次就可以获得65个十六进制数字,然后可以丢弃最后一位数字。 - Mark Dickinson
我注意到了这个问题。上面的 strtrim 解决方案总是生成以 0 开头的十六进制数。但是,有些 64 位十六进制数以 a、b、...、f 开头。此外,上述 64 位十六进制的子部分也都以 0 开头,这破坏了均匀性,正如您所说的那样。当然,我希望能够实现均匀分布。 - Erdogan CEVHER
@MarkDickinson,通过5 * 13-1 = 64狩猎是不可能的,因为.dec.to.hex甚至不能完成.dec.to.hex(2^31),更不用说.dec.to.hex(2^52)了。 - Erdogan CEVHER

0
library(fBasics)
strtrim(paste(sapply(1:11, function(i) .dec.to.hex(abs(ceiling(rnorm(1) * 1e6)))), collapse=""), 64)
# 08FBFA019B4930E2AF707AFEE08A0F90D765E05757607609B0691190FC54E012

让我们来检查一下:

nchar(strtrim(paste(sapply(1:11, function(i) .dec.to.hex(abs(ceiling(rnorm(1) * 1e6)))), collapse=""), 64)) # 64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接