Насколько предсказуемо NEWSEQUENTIALID?

Согласно документации Microsoft на NEWSEQUENTIALID, вывод NEWSEQUENTIALID предсказуем. Но насколько предсказуемо предсказуемо? Скажем, у меня есть GUID, который был сгенерирован NEWSEQUENTIALID как тяжело было бы:

  • Рассчитать следующее значение?
  • Рассчитать предыдущее значение?
  • Рассчитать первое значение?
  • Рассчитать первое значение, даже не зная никаких GUID?
  • Рассчитать количество строк? Например, при использовании целых чисел, /order?id=842 говорит мне, что в приложении 842 заказа.

Ниже приведена некоторая справочная информация о том, что я делаю и каковы различные компромиссы.

Одно из преимуществ безопасности использования GUID над целыми числами в качестве первичных ключей заключается в том, что GUID трудно угадать. Например, хакер видит URL-адрес как /user?id=845 он может попытаться получить доступ /user?id=0, поскольку вполне вероятно, что первый пользователь в базе данных является администратором. Более того, хакер может перебрать /user?id=0..1..2 быстро собрать всех пользователей.

Аналогичным образом, недостатком целых является то, что они пропускают информацию. /order?id=482 говорит мне, что у интернет-магазина было 482 заказа с момента его реализации.

К сожалению, использование GUID в качестве первичных ключей имеет известные недостатки производительности. С этой целью SQL Server представил NEWSEQUENTIALID функция. В этом вопросе я хотел бы узнать, насколько предсказуемы результаты NEWSEQUENTIALID является.

4 ответа

Решение

Основная функция ОС UuidCreateSequential, Значение получено из MAC-адреса одной из ваших сетевых карт и добавочного значения для каждой загрузки. См. RFC4122. SQL Server выполняет некоторую перестановку байтов для правильной сортировки результатов. Таким образом, ценность в некотором смысле очень предсказуема. В частности, если вы знаете значение, вы можете сразу же предсказать диапазон аналогичного значения.

Однако нельзя предсказать эквивалент id=0 и не может предсказать, что 52DE358F-45F1-E311-93EA-00269E58F20D означает, что в магазине продано не менее 482 предметов.

Единственное "одобренное" случайное поколение CRYPT_GEN_RANDOM (который оборачивает CryptGenRandom) но это, очевидно, ужасный ключевой кандидат.

В большинстве случаев следующий newsequentialid можно предсказать, взяв текущее значение и добавив единицу к первой шестнадцатеричной паре.

Другими словами:

1E 29E599-45F1-E311-80CA-00155D008B1C

сопровождается

1F 29E599-45F1-E311-80CA-00155D008B1C

сопровождается

20 29E599-45F1-E311-80CA-00155D008B1C

Иногда последовательность перезапускается с нового значения.

Итак, это очень предсказуемо

NewSequentialID это обертка вокруг функции Windows UuidCreateSequential

• Рассчитать следующее значение? да

Microsoft говорит:

Если вас беспокоит конфиденциальность, не используйте эту функцию. Можно угадать значение следующего сгенерированного GUID и, следовательно, получить доступ к данным, связанным с этим GUID.

Так что это возможность получить следующее значение. Я не нахожу информацию, если можно получить предварительную.

от: http://msdn.microsoft.com/en-us/library/ms189786.aspx

редактировать: еще несколько слов о NEWSEQUENTIALID и безопасности: http://vadivel.blogspot.com/2007/09/newid-vs-newsequentialid.html

Редактировать: NewSequentialID содержит MAC-адрес сервера (или один из них), поэтому знание последовательного идентификатора дает потенциальному злоумышленнику информацию, которая может быть полезна как часть защиты или DoS-атаки. От: Есть ли недостатки использования NewSequentialID?

Вы можете попробовать этот код:

DECLARE @tbl TABLE (
    PK uniqueidentifier DEFAULT NEWSEQUENTIALID(),
    Num int
)
INSERT INTO @tbl(Num) values(1),(2),(3),(4),(5)
select * from @tbl

На моей машине за это время есть результат:

PK                                      Num
52DE358F-45F1-E311-93EA-00269E58F20D    1
53DE358F-45F1-E311-93EA-00269E58F20D    2
54DE358F-45F1-E311-93EA-00269E58F20D    3
55DE358F-45F1-E311-93EA-00269E58F20D    4
56DE358F-45F1-E311-93EA-00269E58F20D    5

Вы должны попробовать это несколько раз в разное время / дату, чтобы интерполировать поведение. Я пробовал запустить его несколько раз, и первая часть меняется каждый раз (вы видите результаты: 52...,53...,54... и т. Д.). Я ждал некоторое время, чтобы проверить это, и через некоторое время вторая часть также увеличивается. Я полагаю, инцементация продолжается во всех частях. В основном это выглядит просто +=1 Incementation превращается в Guid.

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

Если вам нужен последовательный идентификатор GUID и вы хотите контролировать значения, вы можете использовать Последовательности.

Образец кода:

select cast(cast(next value for [dbo].[MySequence] as varbinary(max)) as uniqueidentifier)
Другие вопросы по тегам