从电子邮件地址到准随机数[关闭]


10

我的目标:

我想要一个具有电子邮件地址并输出1、2、3或4的准随机数的函数。

一点细节:

通过准随机数,我的意思是给定一个典型的电子邮件地址,获得值1、2、3或4的概率大致相等,并且电子邮件地址的明显系统属性(例如域名)不会影响获得值1、2、3或4的可能性。

一点背景:

我有一个以询问方式编写的在线实验,参与者有两次登录。我想将参与者随机分配到四个组之一。尽管对于一个会话来说这很容易做到(我只能使用随机数生成器),但是我需要某种方式来记住跨会话的分配。因此,我认为我可以从参与者电子邮件中提取一个准随机组分配。我在可用的功能集中也受到限制(完整列表请参见此处)。字符串函数是:较低上部大写concat搜索replaceall包含以结尾开头的字符串,带有子字符串trim trimright trimleft长度格式求值

初步想法:

我考虑过尝试提取电子邮件地址的一组功能,这些功能返回的概率分别为1、2、3或4。然后,我可以对这些属性求和并得到mod 4 plus 1。因此,假设类似中心极限定理,我可能会接近。

我可能想到的功能:

  • 字符串长度
  • 第一个“ a”,“ b”等的位置

1
一个非常有趣的问题。您手边有一个“典型的电子邮件地址”示例吗?此外,不能保证访问者的电子邮件地址确实具有另一个/不同的结构,但是由于您只是在寻找一个近似值...。第二个问题:您是否可以设置RNG的种子?
steffen

6
听起来像您想要一个“哈希函数”:en.wikipedia.org/wiki/Hash_function 尽管这是在计算机科学领域而不是统计领域,所以我不确定它属于CrossValidated。
一站式服务,

1
hmpf;)...我打算写同样的东西。@Jeromy:尤其是网站的这一部分(en.wikipedia.org/wiki/…)对您来说可能很有趣。
steffen 2011年

@onestop感谢您提供有关标签的提示。关于问题是否在站点主题上,我认为参与者随机分配到各个组与研究设计具有内在联系,而研究设计又与数据推断有关。
Jeromy Anglim

1
@Jeremy哈希函数与主题标签根本不一样!不过,我明白您关于学习设计的观点。我承认没有正确阅读您的全部问题。
一站式

Answers:



3

为什么不对电子邮件中每个可能的字符都有一个数字查找表。然后将数字连接起来形成种子。例如,

A 1
B 2
C 3
....
@ 27
....

因此abc @ ccc将转换为12327333。这将为您提供每个人的唯一种子。然后,您将使用它来生成1、2、3、4。


从您的问题来看,您似乎并不介意“快速而肮脏的解决方案”。我的解决方案的一个问题是电子邮件地址不是随机的-例如,您可能会收到很少包含字母“ z”的电子邮件地址,但是所有电子邮件地址都包含“ @”。


关于上述方法的一个小注释是,电子邮件地址中有一堆有效字符(尤其是标点符号),如果要这样做,您需要考虑一下。
dsolimano 2011年

@dsol:我同意。您很容易在电子邮件地址中被“ +”号吸引。为了获得快速而又肮脏的解决方案,我可能会跳过在查询表中未指定的所有标点符号。
csgillespie 2011年

1

除了其他出色的答案之外,我仅将用R语言给出一个简单的示例,以显示一个非常简单的哈希函数,该哈希函数足以满足此目的。为了获得一些电子邮件地址作为测试数据,我得到了一个字符向量,其中包含我计算机上安装的(太多!)R软件包的维护者的电子邮件:

library(stringr) # on CRAN 
last <- function(x) { return( x[length(x)] ) }

INST  <-  installed.packages(priority="NA", fields=c("Maintainer"))
Maintainer <- INST[, "Maintainer"]
Mlist <- str_split(Maintainer, "[[:blank:]]")
Maddr <- sapply(Mlist, FUN=last)
Maddr <- str_replace(Maddr, "[<>]", "")
Maddr <- unique(Maddr)

然后,我定义一个简单的函数,该函数从电子邮件地址中的每个字符获取一些数字,将其相加,计算余数模4并加1,因此它将始终返回结果1,2,3或4之一:

apply_to_each_char  <-  function(w, FUN) {
    ww <-  str_split(w, "")[[1]]
    res <- sapply(ww, FUN)
    } # END apply_to_each_char
charsum <- function(word) { # length-one char vector
    sum0 <- sum( apply_to_each_char(word, function(w) as.integer(charToRaw(w)) ))
    return( 1 + sum0 %% 4)
    } # end charsum

然后应用它:

hashes <- sapply(Maddr, charsum)
table(hashes)
hashes
  1   2   3   4 
542 511 562 552 

我们可以观察到,结果分布接近均匀。


0

您可以尝试将每个字符转换为一个ascii数字,将它们全部相乘以强制溢出,然后对最低有效位执行模运算。如果这还不够伪随机,则可以对数字进行一点位移...

-拉尔夫·温特斯


2
我认为乘法不是最好的主意。尤其是如果您的初始溢出是常规的1-以2的幂为模,您将得到很多偶数因数,因此大多数低位将为0。相反,将数字加在一起会更好。如果您需要更好的随机性,请使用某种哈希函数并使用结果的任何位。如果您希望很难猜测除您之外的其他人的结果,请使用加盐的强密码散列函数。
Erik P.

同意 只是想提出一个想法,以说明移位以生成(大约)伪随机数。
拉尔夫·温特斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.