이메일 주소에서 준 난수로 [닫힘]

나의 목표:

전자 메일 주소를 사용하여 준 난수 1, 2, 3 또는 4를 출력하는 기능을 갖고 싶습니다.

약간의 세부 사항 :

준 난수 (Quasi-random) 숫자로, 나는 전형적인 이메일 주소가 주어지면 1, 2, 3 또는 4의 값을 얻는 확률이 거의 같고 도메인 이름과 같은 이메일 주소의 명백한 체계적 속성은 1, 2, 3 또는 4의 값을 얻을 확률에 영향을 미치지 않습니다.

작은 배경 :

나는 작성된 온라인 실험이 inquisit 참가자가 두 차례에 로그인합니다. 네 그룹 중 하나에 무작위로 참가자를 할당하고 싶습니다. 이것은 한 세션에 대해 수행하기 쉽지만 (난수 생성기를 사용할 수 있음) 세션 간 할당을 기억하는 방법이 필요합니다. 따라서 참가자 이메일에서 준 무작위 그룹 할당을 추출 할 수 있다고 생각했습니다. 나는 또한 내가 가진 기능 세트에 제한이 있습니다 ( 전체 목록은 여기를 참조하십시오 ). 문자열 함수는 다음과 같습니다.

초기 생각 :

나는 거의 동일한 확률로 1, 2, 3 또는 4의 값을 반환하는 전자 메일 주소의 기능 집합을 추출하려고 시도했습니다. 그런 다음 이러한 속성을 합산하여 mod 4 + 1을 얻을 수 있습니다. 따라서 중심 제한 정리와 같은 것을 가정하면 가까이 갈 수 있습니다.

내 마음에 온 가능한 기능 :

  • 끈의 길이
  • 첫 번째 “a”, “b”등의 위치


답변

해시 함수를 찾으십시오 (예 : http://en.wikipedia.org/wiki/Hash_function).


답변

전자 우편의 가능한 각 문자에 대한 룩업 테이블 만 있으면 어떨까요? 그런 다음 숫자를 연결하여 씨앗을 만듭니다. 예를 들어

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

따라서 abc @ ccc는 12327333으로 변환됩니다. 그러면 각 사람에게 고유 한 씨앗이 제공됩니다. 그런 다음 이것을 사용하여 1, 2, 3, 4를 생성합니다.


귀하의 질문에서 “빠르고 더러운 해결책”을 신경 쓰지 않는 것 같습니다. 내 솔루션의 한 가지 문제는 전자 메일 주소가 임의적이지 않다는 것입니다. 예를 들어 문자 “z”가 포함 된 전자 메일 주소는 거의 없지만 모든 전자 메일 주소에는 “@”가 포함됩니다.


답변

다른 훌륭한 답변 외에도 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

결과 분포가 균일에 가깝다는 것을 알 수 있습니다.


답변

각 문자를 ASCII 숫자로 변환하고, 모두 곱하여 오버플로를 강제 한 다음 가장 작은 자릿수에서 모듈러스 연산을 수행 할 수 있습니다. 이것이 의사 난수 (pseudo-random)가 아니면 숫자를 조금씩 시프트 할 수 있습니다.

랄프 윈터스


답변