PHP короткое поколение уникального идентификатора с помощью auto_increment?

Для простоты я сделал это:

/* Constants.h */
#define myColor [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0]

Не забудьте пропустить ';' так что вы можете использовать его как нормальное выражение.

Я не уверен, что с этим подходом что-то не так с технической точки зрения, но он работает нормально и избегает ошибки инициализатора констант во время компиляции - этот код эффективно застрял на месте, где бы вы ни поместили «myColor», поэтому он не никогда не скомпилируется, пока вы его не используете.

7
задан Daren Schwenke 30 October 2009 в 22:13
поделиться

8 ответов

Вам понадобится что-то правильное по конструкции, то есть функция перестановки: это функция, которая выполняет взаимно однозначное обратимое отображение одного целого числа (вашего последовательного счетчика) в другое. . Некоторые примеры (любая их комбинация также должна работать):

  • инвертирование некоторых битов (fi с использованием XOR, ^ в PHP)
  • замена местами битов (($ i & 0xc) >> 2 | ( $ i & 0x3) << 2), или просто изменив порядок всех битов на противоположный
  • , добавив постоянное значение по модулю вашего максимального диапазона (должно быть с коэффициентом два, если вы объединяете это с указанными выше)

Пример: эта функция преобразует 0, 1, 2, 3, 5, .. в 13, 4, 12, 7, 15, .. для чисел до 15:

$i=($input+97) & 0xf;
$result=((($i&0x1) << 3) + (($i&0xe) >> 1)) ^ 0x5;

РЕДАКТИРОВАТЬ

Более простой способ - используйте линейный конгруэнтный генератор (LCG, который обычно используется для генерации случайных чисел), который определяется формулой вида:

X_n+1 = (a * X_n + c) mod m

Для хороших значений a, c и m, последовательность X_0, X_1 .. X_m-1 будет содержать все числа от 0 до m-1 ровно один раз.Теперь вы можете начать с линейно возрастающего индекса и использовать значение next в последовательности LCG в качестве «секретного» ключа.

EDIT2

Реализация: Вы можете разработать свои собственные параметры LCG , но если вы ошибетесь, он не охватит весь диапазон (и, следовательно, будет иметь дубликаты), поэтому я буду использовать здесь опубликованный и опробованный набор параметров из ] этот документ :

a = 16807, c = 0, m = 2147483647

Это дает вам диапазон 2 ** 31. С pack () вы можете получить результирующее целое число в виде строки, base64_encode () делает его читаемой строкой (до 6 значащих символов, 6 бит на байт), так что это может быть ваша функция:

substr(base64_encode(pack("l", (16807 * $index) % 2147483647)), 0, 6)
6
ответ дан 7 December 2019 в 07:46
поделиться

вы можете использовать побитовое XOR для скремблирования некоторых битов:

select thefield ^ 377 from thetable;

+-----+---------+
| a   | a ^ 377 |
+-----+---------+
| 154 |     483 |
| 152 |     481 |
|  69 |     316 |
|  35 |     346 |
|  72 |     305 |
| 139 |     498 |
|  96 |     281 |
|  31 |     358 |
|  11 |     370 |
| 127 |     262 |
+-----+---------+
1
ответ дан 7 December 2019 в 07:46
поделиться

Я думаю это никогда не будет по-настоящему безопасным, так как вам нужно только найти метод шифрования за короткой уникальной строкой, чтобы захватить идентификатор. Действительно ли в ваших условиях такая проблема возникает при проверке коллизий в цикле?

поскольку вам нужно только найти метод шифрования за короткой уникальной строкой, чтобы захватить идентификатор. Действительно ли в ваших условиях такая проблема возникает при проверке коллизий в цикле?

поскольку вам нужно только найти метод шифрования за короткой уникальной строкой, чтобы захватить идентификатор. Действительно ли в ваших условиях такая проблема возникает при проверке коллизий в цикле?

0
ответ дан 7 December 2019 в 07:46
поделиться

MD5 увеличивающегося числа должно быть хорошо, но я беспокоюсь, что если вы усечете свой MD5 (который обычно составляет 128 бит) до 5-8 символов, вы почти наверняка будете нарушая его способность действовать как уникальная подпись ...

-1
ответ дан 7 December 2019 в 07:46
поделиться

Если вы не можете использовать поле с автоматическим приращением и хотите абсолютно уникального значения, используйте UUID . Если вы решите использовать что-нибудь еще (кроме автоматического увеличения), было бы глупо НЕ проверять коллизии.

0
ответ дан 7 December 2019 в 07:46
поделиться

Вероятно, вы могли бы сгенерировать хэш MD5 текущего даты и времени / случайного числа, усечь его до нужной длины (5-8 символов) и сохранить как поле id.

Если вы храните эту информацию в базе данных, вам не нужно использовать цикл for для проверки коллизий, но вы можете просто выполнить оператор select - что-то вроде

SELECT count(1) c FROM Table WHERE id = :id

, где: id будет новым сгенерированным идентификатором. Если c больше 0, значит, вы знаете, что он уже существует.

РЕДАКТИРОВАТЬ

Возможно, это не лучший способ сделать это. Но я попробую, так что я думаю, что вам нужно каким-то образом преобразовать числа в уникальную короткую строку, и это не будет происходить последовательно.

Я думаю, как вы сказали, кодировка base64 уже сокращает число преобразование строк. Чтобы избежать проблемы с последовательностью, вы могли бы иметь некоторое сопоставление между автоматически сгенерированными идентификаторами и некоторым «случайным» значением (уникальное сопоставление). Затем вы можете кодировать base64 это уникальное значение.

Вы можете сгенерировать это отображение следующим образом. Имейте временную таблицу для хранения значений от 1 до 10 000 000. Отсортируйте его в случайном порядке и сохраните в таблице Map.

INSERT INTO MappingTable (mappedId) SELECT values FROM TemporaryTable ORDER BY RAND()

Где MappingTable будет иметь идентификатор 2 полей (ваш автоматически сгенерированный идентификатор будет сравнивать его) и mappedId (для которого вы должны сгенерировать кодировку base64) .

По мере приближения к 10 000 000 вы можете повторно запустить приведенный выше код и изменить значения во временной таблице на 10 000 001–20 000 000 или что-то в этом роде.

Вы можете сгенерировать это отображение следующим образом. Имейте временную таблицу для хранения значений от 1 до 10 000 000. Отсортируйте его в случайном порядке и сохраните в своей таблице Map.

INSERT INTO MappingTable (mappedId) SELECT values FROM TemporaryTable ORDER BY RAND()

Где MappingTable будет иметь идентификатор 2 полей (ваш автоматически сгенерированный идентификатор будет сравнивать его) и mappedId (для которого вы должны сгенерировать кодировку base64) .

По мере приближения к 10 000 000 вы можете повторно запустить приведенный выше код и изменить значения во временной таблице на 10 000 001–20 000 000 или что-то в этом роде.

Вы можете сгенерировать это отображение следующим образом. Имейте временную таблицу для хранения значений от 1 до 10 000 000. Отсортируйте его в случайном порядке и сохраните в своей таблице Map.

INSERT INTO MappingTable (mappedId) SELECT values FROM TemporaryTable ORDER BY RAND()

Где MappingTable будет иметь идентификатор 2 полей (ваш автоматически сгенерированный идентификатор будет сравнивать его) и mappedId (для которого вы должны сгенерировать кодировку base64) .

По мере приближения к 10 000 000 вы можете повторно запустить приведенный выше код и изменить значения во временной таблице на 10 000 001–20 000 000 или что-то в этом роде.

1
ответ дан 7 December 2019 в 07:46
поделиться

MD5 увеличивающегося числа должно быть хорошо, но я беспокоюсь, что если вы усекаете свой MD5 (который обычно 128 бит) до 5-8 персонажей, вы почти наверняка наносить ущерб его способности действовать как уникальная подпись ...

Совершенно верно. Особенно, если вы достигнете 80% вероятности столкновения, усеченный MD5 будет так же хорош, как и любое случайное число, чтобы гарантировать уникальность само по себе, т.е. бесполезно.

Но поскольку вы все равно используете базу данных, почему бы просто не использовать УНИКАЛЬНЫЙ ИНДЕКС? Таким образом, проверка уникальности выполняется (гораздо более эффективно, чем использование цикла) самим MySQL. Просто попробуйте выполнить INSERT с вашим ключом, сгенерированным MD5, и если это не удастся, попробуйте еще раз ...

0
ответ дан 7 December 2019 в 07:46
поделиться

В этом сообщении в блоге есть что-то близкое к тому, что вам нужно.

http://kevin.vanzonneveld.net/techblog/article/create_short_ids_with_php_like_youtube_or_tinyurl/

0
ответ дан 7 December 2019 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: