7

PostgreSQLのmd5()機能をテストしているときに、非常に奇妙な動作に気づきました。

期待どおりに動作します

SELECT md5('abc')
--"900150983cd24fb0d6963f7d28e17f72"

ただし、クエリでmd5()関数を使用する:

SELECT request_id, md5(request_id)
FROM Request
ORDER BY request_id

このエラーが発生します:

ERROR:  function md5(integer) does not exist
LINE 1: SELECT request_id, md5(request_id)
                           ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

********** Error **********

ERROR: function md5(integer) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 20

最初のクエリで機能した場合、関数が存在しないのはどうしてですか?私は何を間違っているのですか。md5()SELECTクエリで使用する正しい方法は何ですか?

4

4 に答える 4

14

この関数は、パラメーターとしてテキストを想定しています。キャスト:

SELECT request_id, md5(request_id::text)
FROM Request
ORDER BY request_id

整数パラメータを受け入れるmd5という名前の関数は存在しませんが、作成できます。

create function md5(integer)
returns text as $$

select md5($1::text);

$$ language sql immutable;

次に、md5には3つの署名があります。

=> \df md5
                          List of functions
   Schema   | Name | Result data type | Argument data types |  Type  
------------+------+------------------+---------------------+--------
 pg_catalog | md5  | text             | bytea               | normal
 pg_catalog | md5  | text             | text                | normal
 public     | md5  | text             | integer             | normal

この回答へのコメントで指摘されているように、整数のテキスト表現のmd5ハッシュはあなたが望むものではないかもしれません。byteaバイナリのハッシュを取得するには、パラメータを受け入れるmd5署名を使用する必要があります。

select md5(('\x' || right('0000000' || to_hex(200), 8))::bytea);
               md5                
----------------------------------
 b7b436d004c1cc0501bee9e296d2eaa4

そして、以前に作成した関数を置き換えます。

create or replace function md5(integer)
returns text as $$

select md5(('\x' || right('0000000' || to_hex($1), 8))::bytea);

$$ language sql immutable;
于 2013-03-24T17:21:01.407 に答える
3

一般に、整数のmd5を使用することはあまり意味がありません。シーケンスを不明瞭にしようとしている可能性が高いため、順番にセミランダムに表示されます。もしそうなら、はるかに良い方法があります:

pseudo_encryptPostgreSQLwikiにリストされている関数を使用します。これは、整数のmd5を取得して(おそらく)それを切り捨てようとするよりもはるかに賢明です。

上記は強力な暗号のランダム性を提供しませんが、あなたのアプローチも提供しません。要求IDをセキュリティ上の理由で一見しただけではなく、本当に予測できないものにする必要がある場合は、強力な暗号化乱数ジェネレーターを使用し、タイムウィンドウなどを使用して重複に対処する準備をしておく必要があります。

于 2013-03-24T22:37:28.233 に答える
1

エラーは少し誤解を招く可能性があります。md5()関数は存在しますが、整数を処理するためだけのものではありません。埋め込みCAST()関数を使用して整数フィールドをテキストに変換すると、次のように機能します。

SELECT request_id, md5(CAST(request_id AS TEXT))
FROM Request
ORDER BY request_id

--1;"c4ca4238a0b923820dcc509a6f75849b"
--2;"c81e728d9d4c2f636f067f89cc14862c"
--etc
于 2013-03-24T17:22:16.910 に答える
0

私は、レコードを検索するために使用できる、自明ではなく、繰り返されない値を生成しようとしています。

必要なのは全単射ハッシュです。CRCカスタムC関数でCPU関数を使用しています。機能を持たないCPUの場合は、ルックアップテーブルを使用できます。

このアプローチにより、一意の32ビット入力ごとに一意の「乱数」が得られることが保証されます。

C関数を生成する方法を知っている場合(簡単ではありません)、CRCの使用方法を調べるのは簡単な作業です。

于 2017-06-08T17:41:15.487 に答える