2013-03-24 20 views
5

जबकि PostgreSQL's md5() function परीक्षण मैं बहुत विचित्र व्यवहार देखा: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 

समारोह नहीं कैसे मौजूद कर सकते हैं अगर यह पहली क्वेरी में काम किया? मैं गलत क्या कर रहा हूं; एक SELECT क्वेरी में md5() का उपयोग करने का सही तरीका क्या है?

+2

यह बिल्कुल विचित्र प्रतीत नहीं होता है। पहली क्वेरी में, आपने टेक्स्ट पास किया, जबकि दूसरे में आप पूर्णांक पास करने का प्रयास कर रहे हैं। – us2012

+0

@ us2012: हाँ, यह अंतर है। –

+0

सामान्य रूप से यह पूर्णांक के md5 को लेने के लिए अधिक समझ में नहीं आता है, इसलिए मुझे इसमें दिलचस्पी होगी कि आप ऐसा करने का प्रयास क्यों कर रहे हैं। –

उत्तर

10

फ़ंक्शन पैरामीटर के रूप में टेक्स्ट की अपेक्षा करता है। यह कास्ट:

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

एक पूर्णांक पैरामीटर को स्वीकार md5 नाम के एक समारोह में मौजूद नहीं है लेकिन आप इसे बना सकते हैं:

=> \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 

:

create function md5(integer) 
returns text as $$ 

select md5($1::text); 

$$ language sql immutable; 

फिर md5 के लिए 3 हस्ताक्षर नहीं होगा जैसा कि इस जवाब में टिप्पणियों की ओर इशारा किया गया है, पूर्णांक के पाठ प्रतिनिधित्व का md5 हैश वह नहीं हो सकता है जो आप चाहते हैं। द्विआधारी md5 हस्ताक्षर एक bytea पैरामीटर को स्वीकार किया जाना चाहिए की हैश है करने के लिए:

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; 
+0

सच्ची कहानी। मैंने प्रश्न पोस्ट करने के ठीक बाद इसे ठीक से समझ लिया। धन्यवाद क्लोडोल्डो। –

+2

ध्यान दें कि टेक्स्ट को पूर्णांक कास्टिंग करने का अर्थ है कि आप पूर्णांक * के पाठपरक प्रतिनिधित्व के एमडी 5 ले रहे हैं। अन्य प्रणालियों के साथ संवाद करते समय यह आपके इरादे से नहीं हो सकता है। यदि आप वास्तव में पूर्णांक के बाइनरी प्रतिनिधित्व के एमडी 5 को लेना चाहते हैं तो आपको उचित बाइनरी प्रतिनिधित्व के एमडी 5 (32-बिट थोड़ा एंडियन पर हस्ताक्षर करने के लिए, पीएल/पर्ल, पीएल/पायथन इत्यादि जैसी प्रक्रियात्मक भाषा का उपयोग करना होगा) उदाहरण)। –

+1

@ क्रेग अच्छा बिंदु। लेकिन ऐसा लगता है कि एक प्रक्रियात्मक भाषा आवश्यक नहीं है। या क्या मैं कुछ न कुछ भूल रहा हूं? –

0

त्रुटि एक छोटे से भ्रामक है; md5() फ़ंक्शन मौजूद है, बस पूर्णांक पर काम करने के लिए नहीं। एक एम्बेडेड CAST() फ़ंक्शन का उपयोग पाठ में पूर्णांक क्षेत्र परिवर्तित करने के लिए, और यह काम करेगा:

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

--1;"c4ca4238a0b923820dcc509a6f75849b" 
--2;"c81e728d9d4c2f636f067f89cc14862c" 
--etc 
3

सामान्य तौर पर यह बहुत मतलब नहीं है एक पूर्णांक के md5 लेने के लिए। ऐसा लगता है कि आप अनुक्रम को अस्पष्ट करने की कोशिश कर रहे हैं ताकि यह अर्द्ध-यादृच्छिक क्रम में दिखाई दे। यदि हां, तो एक बेहतर तरीका है:

pseudo_encrypt function listed on the PostgreSQL wiki का उपयोग करें। यह एक पूर्णांक के md5 को लेने की कोशिश करने से पहले है (संभवतः) इसे छोटा कर दें।

उपरोक्त मजबूत क्रिप्टोग्राफिक यादृच्छिकता प्रदान करता है, लेकिन न ही आपका दृष्टिकोण करता है। यदि आपको अपने अनुरोध आईडी को सुरक्षा कारणों से वास्तविक रूप से अप्रत्याशित होने की आवश्यकता है, तो अनौपचारिक नज़र में केवल स्पष्ट नहीं है, तो आपको एक मजबूत क्रिप्टोग्राफिक यादृच्छिक संख्या जनरेटर का उपयोग करना चाहिए और समय खिड़कियों आदि का उपयोग करके डुप्लिकेट से निपटने के लिए तैयार रहना चाहिए।

+0

मैं सिर्फ एक गैर-स्पष्ट, गैर-दोहराव, मूल्य उत्पन्न करने की कोशिश कर रहा हूं जिसका उपयोग रिकॉर्ड को देखने के लिए किया जा सकता है। तो मेरा उज्ज्वल (?) विचार टबल के पीएल पर कुछ प्रकार की एन्क्रिप्शन करना है। यह सुरक्षा-द्वारा-गुमनाम आवश्यक है क्योंकि आकस्मिक उपयोगकर्ता (टिकट अनुरोधकर्ता) में लॉग इन नहीं होंगे। वैसे भी, मैं इस "एन्क्रिप्शन" करने के लिए 'REPLACE (request_id :: text, '1234567890', 'abcdefghij') का उपयोग करने पर उतरा। –

+0

पीएस - आपका "अवागा! अवागा!" अभी भी मुझे दरारें। –

+1

@ जेरोमीफ्रेंच मैं क्या कह सकता हूं, मुझे होली से प्यार है और चुटकुले बनाने की तरह ही हमें बूढ़े लोग मिलेंगे ;-)। एक व्याख्याता की तरह मैं यूनी में था जो उसकी बातचीत में बेहद मजेदार बंदर संदर्भ बनाते थे; थियेटर में हम में से चार या पांच हंसते हुए टूट जाएंगे और हर कोई हमें देखेगा जैसे हम काफी पागल हो गए थे। –

0

I'm just trying to generate a non-obvious, non-repeating, value which can be used to look-up a record.

आपको एक जैविक हेश की आवश्यकता है। मैं कस्टम सी फ़ंक्शन में CRC CPU फ़ंक्शन का उपयोग करता हूं। उन CPUs के लिए जिनके पास फ़ंक्शन नहीं है, कोई एक लुकअप टेबल का उपयोग कर सकता है।

यह दृष्टिकोण आपको प्रत्येक अद्वितीय 32-बिट इनपुट के लिए एक अद्वितीय "यादृच्छिक दिखने वाला" नंबर देने की गारंटी देता है।

यदि आप जानते हैं कि सी फ़ंक्शन कैसे उत्पन्न करें (तुच्छ नहीं), तो यह सीआरसी का उपयोग करने के तरीके को देखने का एक आसान काम होगा।

संबंधित मुद्दे