Как побитовое сравнение строки

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

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

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

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

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

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


person Tyson of the Northwest    schedule 03.06.2009    source источник


Ответы (2)


Я нашел интересное решение, но я не уверен, насколько оно логически правильно, потому что я не очень хорошо знаком с тем, как 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 я показал, что строка, содержащая комбинацию символов, совпадающую с позициями символов в других ключах, может дать ложное срабатывание. Но могу ли я обойти это с помощью строгих правил в отношении строк разрешений? Каждый тип ресурса имеет имя, и каждый тип ресурса имеет ограниченное количество связанных разрешений. Что-то вроде «Блог….Написать сообщение», «Блог…Опубликовать сообщение», «Блог….Модерировать сообщение», «Подкаст…..Загрузить», «Подкаст…. ...Publish", чтобы компенсировать возрастающую вероятность коллизии, поскольку длина строки мало влияет на скорость PHP.

person Tyson of the Northwest    schedule 03.06.2009

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

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

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

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

person Danut Enachioiu    schedule 03.06.2009