Этот синтаксис недействителен в Oracle. Вы можете сделать это:
UPDATE table1 SET table1.value = (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC)
WHERE table1.UPDATETYPE='blah'
AND EXISTS (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC);
Или вы могли бы быть в состоянии сделать это:
UPDATE
(SELECT table1.value as OLD, table2.CODE as NEW
FROM table1
INNER JOIN table2
ON table1.value = table2.DESC
WHERE table1.UPDATETYPE='blah'
) t
SET t.OLD = t.NEW
(Это зависит от того, рассматривается ли встроенное представление обновляется Oracle).
После некоторых экспериментов я пришли к выводу, что это связано со способом обращения с солью. Соль не считается буквальным текстом, а скорее строкой в кодировке base64, так что 22 байта солевых данных фактически представляют собой 16-байтовую строку ( floor (22 * 24/32) == 16
) соли. Команда "Попался!" Однако в этой реализации, как и в Unix crypt, используется «нестандартный» алфавит base64. Если быть точным, он использует этот алфавит:
./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$
65-й символ, ' $
', является символом заполнения.
Теперь функция crypt ()
, похоже, способна принимать соль любой длины, меньшей или равной ее максимальной, и молча обрабатывать любые несоответствия в base64, отбрасывая любые данные, которые не соответствуют ' t составляют еще один полный байт. Функция crypt полностью выйдет из строя, если вы передадите ей символы в соли, которые не являются частью ее алфавита base64, что лишь подтверждает эту теорию ее работы.
Возьмем воображаемую соль ' 1234
'. Это полностью соответствует base64, поскольку представляет 24 бита данных, то есть 3 байта, и не несет никаких данных, которые необходимо отбросить. Это соль, у которой Len Mod 4
равно нулю. Добавьте к этой соли любой символ, и он станет солью из 5 символов, и Len Mod 4
теперь равно 1.Однако этот дополнительный символ представляет только шесть бит данных и, следовательно, не может быть преобразован в другой полный байт, поэтому он отбрасывается.
Таким образом, для любых двух солей A и B, где
Len A Mod 4 == 0
&& Len B Mod 4 == 1 // these two lines mean the same thing
&& Len B = Len A + 1 // but are semantically important separately
&& A == substr B, 0, Len A
Фактическая соль, используемая crypt ()
для вычисления хэша, фактически будет идентична. В качестве доказательства я привожу пример кода PHP, который можно использовать для демонстрации этого. Соль постоянно вращается полу неслучайным образом (на основе случайного сегмента хэша водоворота текущего времени с точностью до микросекунды), и данные, подлежащие хешированию (здесь называются $ seed
) - это просто текущее время эпохи Unix.
$salt = substr(hash('whirlpool',microtime()),rand(0,105),22);
$seed = time();
for ($i = 0, $j = strlen($salt); $i <= $j; ++$i) {
printf('%02d = %s%s%c',
$i,
crypt($seed,'$2a$07$' . substr($salt, 0, $i)),
$i%4 == 0 || $i % 4 == 1 ? ' <-' : '',
0x0A
);
}
И это дает результат, аналогичный следующему
00 = $2a$07$$$$$$$$$$$$$$$$$$$$$$.rBxL4x0LvuUp8rhGfnEKSOevBKB5V2. <-
01 = $2a$07$e$$$$$$$$$$$$$$$$$$$$.rBxL4x0LvuUp8rhGfnEKSOevBKB5V2. <-
02 = $2a$07$e8$$$$$$$$$$$$$$$$$$$.WEimjvvOvQ.lGh/V6HFkts7Rq5rpXZG
03 = $2a$07$e89$$$$$$$$$$$$$$$$$$.Ww5p352lsfQCWarRIWWGGbKa074K4/.
04 = $2a$07$e895$$$$$$$$$$$$$$$$$.ZGSPawtL.pOeNI74nhhnHowYrJBrLuW <-
05 = $2a$07$e8955$$$$$$$$$$$$$$$$.ZGSPawtL.pOeNI74nhhnHowYrJBrLuW <-
06 = $2a$07$e8955b$$$$$$$$$$$$$$$.2UumGVfyc4SgAZBs5P6IKlUYma7sxqa
07 = $2a$07$e8955be$$$$$$$$$$$$$$.gb6deOAckxHP/WIZOGPZ6/P3oUSQkPm
08 = $2a$07$e8955be6$$$$$$$$$$$$$.5gox0YOqQMfF6FBU9weAz5RmcIKZoki <-
09 = $2a$07$e8955be61$$$$$$$$$$$$.5gox0YOqQMfF6FBU9weAz5RmcIKZoki <-
10 = $2a$07$e8955be616$$$$$$$$$$$.hWHhdkS9Z3m7/PMKn1Ko7Qf2S7H4ttK
11 = $2a$07$e8955be6162$$$$$$$$$$.meHPOa25CYG2G8JrbC8dPQuWf9yw0Iy
12 = $2a$07$e8955be61624$$$$$$$$$.vcp/UGtAwLJWvtKTndM7w1/30NuYdYa <-
13 = $2a$07$e8955be616246$$$$$$$$.vcp/UGtAwLJWvtKTndM7w1/30NuYdYa <-
14 = $2a$07$e8955be6162468$$$$$$$.OTzcPMwrtXxx6YHKtaX0mypWvqJK5Ye
15 = $2a$07$e8955be6162468d$$$$$$.pDcOFp68WnHqU8tZJxuf2V0nqUqwc0W
16 = $2a$07$e8955be6162468de$$$$$.YDv5tkOeXkOECJmjl1R8zXVRMlU0rJi <-
17 = $2a$07$e8955be6162468deb$$$$.YDv5tkOeXkOECJmjl1R8zXVRMlU0rJi <-
18 = $2a$07$e8955be6162468deb0$$$.aNZIHogUlCn8H7W3naR50pzEsQgnakq
19 = $2a$07$e8955be6162468deb0d$$.ytfAwRL.czZr/K3hGPmbgJlheoZUyL2
20 = $2a$07$e8955be6162468deb0da$.0xhS8VgxJOn4skeI02VNI6jI6324EPe <-
21 = $2a$07$e8955be6162468deb0da3.0xhS8VgxJOn4skeI02VNI6jI6324EPe <-
22 = $2a$07$e8955be6162468deb0da3ucYVpET7X/5YddEeJxVqqUIxs3COrdym
Заключение? Дважды. Во-первых, он работает так, как задумано, а во-вторых, знайте, что у вас есть, или не бросайте свою соль.
Похоже, что выходы на самом деле разные. (da $, vs da2) для результата salt_20 и salt_21.