D'une adresse e-mail à un numéro quasi aléatoire [fermé]

10

Mon but:

J'aimerais avoir une fonction qui prend une adresse e-mail et génère un nombre quasi-aléatoire de 1, 2, 3 ou 4.

Un petit détail:

Par nombre quasi-aléatoire, je veux dire que compte tenu d'une population typique d'adresses e-mail, les probabilités d'obtenir une valeur de 1, 2, 3 ou 4 sont à peu près égales, et que les propriétés systématiques évidentes de l'adresse e-mail telles que le nom de domaine n'affecte pas la probabilité d'obtenir une valeur de 1, 2, 3 ou 4.

Un peu d'histoire:

J'ai une expérience en ligne écrite inquisit où les participants se connectent à deux reprises. Je souhaite affecter au hasard les participants à l'un des quatre groupes. Bien que cela soit facile à faire pour une session (je peux simplement utiliser un générateur de nombres aléatoires), j'ai besoin d'un moyen de me souvenir de l'allocation entre les sessions. Ainsi, j'ai pensé que je pouvais extraire une allocation de groupe quasi aléatoire de l'e-mail du participant. Je suis également limité dans l'ensemble des fonctions dont j'ai à ma disposition ( voir ici pour la liste complète ). Les fonctions de chaîne sont les suivantes: tolower toupper capitalize concat search replaceall contient startswith endswith substring trim trimright trimleft longueur format evalu

Réflexions initiales:

J'ai pensé à essayer d'extraire un ensemble de fonctionnalités de l'adresse e-mail qui renvoyaient une valeur de 1, 2, 3 ou 4 avec des probabilités à peu près égales. Ensuite, je pourrais additionner ces propriétés et obtenir le mod 4 plus 1 de cela. Ainsi, en supposant quelque chose comme le théorème de la limite centrale, je pourrais me rapprocher.

Caractéristiques possibles qui me sont venues à l'esprit:

  • longueur de chaîne
  • position du premier "a", "b", etc.
Jeromy Anglim
la source
1
Un problème très intéressant. Avez-vous un échantillon de "population typique d'adresses e-mail" à portée de main? De plus, il n'est pas garanti que les adresses e-mail des visiteurs aient la même structure différente / différente, mais puisque vous ne cherchez qu'une approximation .... Deuxième question: êtes-vous en mesure de définir le germe du RNG?
steffen
6
On dirait que vous voulez une «fonction de hachage»: en.wikipedia.org/wiki/Hash_function C'est dans les domaines de l'informatique plutôt que des statistiques, donc je ne suis pas sûr qu'il appartient à CrossValidated.
2011
1
hmpf;) ... J'avais l'intention d'écrire la même chose. @Jeromy: Surtout cette partie du site ( en.wikipedia.org/wiki/… ) pourrait vous intéresser.
steffen
@onestop Merci pour le conseil sur les hashtags. Quant à savoir si la question est sur le sujet du site, je pense que la répartition aléatoire des participants aux groupes est intrinsèquement liée à la conception de l'étude, qui à son tour est liée aux déductions à partir des données.
Jeromy Anglim
1
@Jeremy Une fonction de hachage n'est pas du tout la même chose qu'un hashtag! Je vois votre point sur la conception de l'étude. J'avoue ne pas avoir bien lu l'intégralité de votre question.
2011

Réponses:

3

Pourquoi ne pas simplement avoir une table de recherche de nombres pour chaque caractère possible dans un e-mail. Ensuite, enchaînez les nombres pour former une graine. Par exemple,

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

Donc abc @ ccc, serait converti en 12327333. Cela vous donnerait une graine unique pour chaque personne. Vous utiliseriez alors ceci pour générer les 1, 2, 3, 4.


De votre question, il semble que cela ne vous dérange pas une "solution rapide et sale". Un problème avec ma solution est que les adresses e-mail ne sont pas aléatoires - par exemple, vous obtiendrez probablement très peu d'adresses e-mail contenant la lettre "z", mais toutes les adresses e-mail contiennent "@".

csgillespie
la source
Une remarque mineure à propos de la méthode ci-dessus est qu'il y a un tas de caractères valides dans les adresses e-mail - la ponctuation en particulier - que vous voudriez considérer si vous faisiez cela.
dsolimano
@dsol: Je suis d'accord. Vous pourriez facilement être pris avec un "+" dans une adresse e-mail. Pour une solution rapide et sale, je sauterais probablement juste les caractères de ponctuation que je n'avais pas spécifiés dans ma table de recherche.
csgillespie
1

En plus d'autres excellentes réponses, je vais simplement donner un exemple simple en langage R pour montrer une fonction de hachage très simple, qui devrait être assez bonne à cet effet. Pour obtenir des adresses e-mail en tant que données de test, j'obtiens un vecteur de caractères avec les e-mails des responsables des (trop nombreux!) Packages R installés sur mon ordinateur:

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)

Ensuite, je définis une fonction simple qui obtient un certain nombre de chaque caractère dans l'adresse e-mail, les ajoute, calcule le reste modulo 4 et ajoute 1, de sorte qu'il renvoie toujours l'un des résultats 1, 2, 3 ou 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

Puis l'appliquer:

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

et nous pouvons observer que la distribution résultante est presque uniforme.

kjetil b halvorsen
la source
0

Vous pouvez essayer de convertir chaque caractère en nombre ascii, en les multipliant tous ensemble pour forcer le débordement, puis en effectuant une opération de module sur les chiffres les moins significatifs. Si ce n'est pas assez pseudo-aléatoire, vous pouvez effectuer un bit-shift les nombres un peu ...

-Ralph Winters

Ralph Winters
la source
2
La multiplication n'est pas la meilleure idée, je pense. Surtout si votre débordement initial est normal - modulo une puissance de 2. Vous obtiendrez beaucoup de facteurs qui sont pairs, donc la plupart de vos bits inférieurs seront 0. Ajouter les nombres ensemble à la place serait déjà beaucoup mieux. Si vous avez besoin d'un caractère aléatoire encore meilleur, utilisez une sorte de fonction de hachage et utilisez n'importe quel bit du résultat. Si vous voulez qu'il soit difficile de deviner quoi que ce soit sur le résultat pour des personnes autres que vous, utilisez une fonction de hachage cryptographique forte et salée.
Erik P.
D'accord. Je voulais juste suggérer une idée pour illustrer le décalage de bits afin de générer (grossièrement) des nombres pseudo-aléatoires.
Ralph Winters