Как побитовое сравнение строки - PullRequest
4 голосов
/ 03 июня 2009

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

Итак, я подумал о том, чтобы взять строку, сгенерировать из нее маску, а затем ИЛИ в поле разрешений. По мере добавления дополнительных разрешений продолжайте ИЛИ их в глобус. Затем, когда вам нужно проверить разрешение и строку с глобусом.

Вопрос в том, как создать маску. Сначала я думал просто о хешировании строки для уникальной маски, однако это возможно, но я не знаю, насколько вероятно, что, поскольку большее количество хеш-значений ИЛИ направлено на глобус, существует потенциал для заполнения глобуса таким образом. Таким образом, и тестирование с разрешением, которого у них нет, но возвращает истинное значение.

if($glob&&$test == $test)

Другая опция будет просто автоматически нумеровать строки разрешений и иметь их маску 2 ^ авто-номер. Но это ограничило бы количество строк разрешений до 64ish.

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

Ответы [ 3 ]

2 голосов
/ 03 июня 2009

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

$key1 = "Access to Black Box";
$key2 = "Managing Black Box";
$key3 = "Nothing too see here";
$key3a = "Nothingg B";
$key3b = "too see";
$glob = "";

$glob = $glob | $key1;
if(($glob & $key1) == $key1){echo "<p>Key one exists in glob: " . $glob;}

$glob = $glob | $key2;
if(($glob & $key2) == $key2){echo "<p>Key one exists in glob: " . $glob;}

if(($glob & $key3) == $key3){echo "<p>Key three exists in glob: " . $glob;}
else{echo "<p>Key three does not exists in glob: " . $glob;}

$glob = $glob | $key3;
if(($glob & $key3) == $key3){echo "<p>Key three exists in glob: " . $glob;}

if(($glob & $key3a) == $key3a){echo "<p>Key three a exists in glob: " . $glob;}

if(($glob & $key3b) == $key3b){echo "<p>Key three b exists in glob: " . $glob;} 
else{echo "<p>Key three b does not exists in glob: " . $glob;}

Выходы:

Key one exists in glob: Access to Black Box
Key two exists in glob: Mcoew{nwobnmckkbox
Key three does not exists in glob: Mcoew{nwobnmckkbox
Key three exists in glob: Oomowoomsooboze
Key three a exists in glob: Oomowoomsooboze
Key three b does not exists in glob: Oomowoomsooboze

Так что это работает, но что бы я смотрел на столкновение мудрым? С помощью key3a я показал, что в строке, содержащей комбинацию символов, которые соответствуют позициям с символами в других ключах, я могу получить ложное срабатывание. Но могу ли я обойти это со строгими правилами в строках разрешений? Каждый тип ресурса имеет имя, и каждый тип ресурса имеет ограниченное количество связанных разрешений. Так что-то вроде «Блог .... Написать сообщение», «Блог ... Опубликовать сообщение», «Блог .... Умеренный пост», «Подкаст ....... Загрузить», «Подкаст .... ... Опубликовать ", чтобы компенсировать растущую вероятность столкновения, поскольку длина строки мало влияет на скорость PHP.

1 голос
/ 03 июня 2009

Основная мысль здесь такова:

Другая опция будет просто автоматически нумеровать строки разрешений и иметь их маску 2 ^ авто-номер. Но это ограничило бы количество строк разрешений до 64ish.

Если ваши строки разрешений действительно независимы друг от друга, то, очевидно, что бы вы ни делали, вам потребуется по крайней мере 1 бит, чтобы сохранить, существует ли разрешение. Обойти это невозможно (это 1 бит реальной, независимой информации).

Возможным решением вашей проблемы будет сжатое кодирование разрешений (скажем, присваивание Int16 каждому) и сохранение списка разрешений пользователя в виде двоичного массива всех его разрешений. Это ужасно, но это смутно решит твою проблему. В зависимости от БД у вас могут быть какие-то типы столбцов массива / коллекции, которые могут сделать это за вас.

0 голосов
/ 03 июня 2009

Поскольку каждая строка уникальна, почему бы не загрузить их из базы данных один раз в хеш-таблицу (или аналог) и кэшировать их на время сеанса пользователя?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...