Я предложил описать, как я «случайно» скремлю 9-значные SSN при создании наборов данных исследований. Это не заменит или не будет содержать SSN. Он переупорядочивает цифры. Трудно вернуть цифры в правильном порядке, если вы не знаете порядок, в котором они были скремблированы. У меня есть ощущение, что это не то, что действительно хочет расспрашивать. Поэтому я счастлив удалить этот ответ, если он считается вне темы.
Я знаю, что у меня 9 цифр. Итак, я начинаю с массивом, который имеет 9 значений индекса в порядке:
$a = array(0,1,2,3,4,5,6,7,8);
Теперь мне нужно повернуть ключ, который я помню в способ для воспроизведения в массиве. Перетасовка должна быть одинаковым для одного и того же ключа каждый раз. Я использую пару трюков. Я использую crc32, чтобы превратить слово в число. Я использую srand/rand для получения предсказуемого порядка случайных значений. Примечание: mt_rand больше не производит такую же последовательность случайных цифр с одним и тем же семенем, поэтому мне нужно использовать rand.
srand(crc32("My secret key"));
usort($a, function($a, $b) { return rand(-1,1); });
Массив $ a по-прежнему имеет цифры от 0 до 8, но они перетасовываются. Если я использую одно и то же ключевое слово, я получаю тот же перетасованный порядок каждый раз. Это позволяет мне повторять это каждый месяц и получать тот же результат. Затем, с перетасованным массивом, я могу выбрать цифры из SSN. Во-первых, я гарантирую, что он имеет 9 символов (некоторые SSN отправляются как целые числа, а ведущее 0 опущено). Затем я создаю маскированный SSN, выбирая цифры, используя $ a.
$ssn = str_pad($ssn, 9, '0', STR_PAD_LEFT);
$masked_ssn = '';
foreach($a as $i) $masked_ssn.= $ssn{$i};
$ masked_ssn теперь будет иметь все цифры в $ ССН, но в другом порядке. Технически есть ключевые слова, которые заставляют $ a стать исходным упорядоченным массивом после перетасовки, но это очень редко.
Надеюсь, это имеет смысл. Если это так, вы можете сделать все это намного быстрее. Если вы превратите исходную строку в массив символов, вы можете перетасовать массив символов. Вам просто нужно каждый раз подбирать rand.
$ssn = "111223333"; // Assume I'm using a proper 9-digit SSN
$a = str_split($ssn);
srand(crc32("My secret key"));
usort($a, function($a, $b) { return rand(-1,1); });
$masked_ssn = implode('', $a);
Это не действительно быстрее в пути, потому что во время выполнения рэнд является довольно дорогой и функция запуска рандов чертовски много больше здесь. Если вы маскируете тысячи значений, как я, вам нужно использовать массив индексов, который перетасовывается только один раз, а не перетасовка для каждого значения.
Теперь, как мне его отменить? Предположим, что я использую первый метод с массивом индексов. Это будет что-то вроде $ a = {5, 3, 6, 1, 0, 2, 7, 8, 4}. Это индексы для исходного SSN в замаскированном порядке. Таким образом, я могу легко создать оригинальный SSN.
$ssn = '000000000'; // I like to define all 9 characters before I start
foreach($a as $i=>$j) $ssn[$j] = $masked_ssn{$i};
Как вы можете видеть, $ i рассчитывает от 0 до 8 через маскированный SSN. $ j рассчитывает 5, 3, 6 ... и помещает каждое значение из маскированного SSN в правильное место в исходном SSN.
Если он должен быть обратимым, то это не хэш; почему бы не просто поразрядный xor с фиксированным значением? –
Я делаю это регулярно. У меня есть набор людей, идентифицированных с SSN. При запуске отчетов для исследователей я подбираю цифры. Я могу расшифровать их, если мне нужно вернуться и добавить больше данных. Я могу опубликовать описание такой функции, как ответ, если хотите. – kainaw
@MarkBaker Не могли бы вы рассказать? Я пробовал простое $ seed^$ значение для всех чисел от 1 до 100 с 34 как семя, и он произвел числа за пределами диапазона. –