2009-09-14 18 views
14

मेरे उपयोगकर्ता डेटाबेस तालिका में, मैं आईडी के रूप में एक उपयोगकर्ता का ईमेल पता का MD5 हैश लेने के रूप में MD5 हैश का प्रतिनिधित्व करते हैं।एक पूर्णांक

उदाहरण: email([email protected]) = id(d41d8cd98f00b204e9800998ecf8427e)

दुर्भाग्य से, मैं अब पूर्णांक मान के रूप में आईडी का प्रतिनिधित्व करने के लिए है - क्रम एक API जहां आईडी केवल एक पूर्णांक हो सकता है उपयोग करने में सक्षम होने के लिए।

अब मैं एक तरह से एक डिकोड भेजने इसे फिर से जब प्राप्त करने के लिए एक पूर्णांक में आईडी एन्कोड करने के लिए की तलाश में हूँ। मैं ये कैसे करूं?

मेरे विचारों अब तक:

  1. convert_uuencode() और convert_uudecode() MD5 हैश
  2. MD5 हैश के हर चरित्र को बदलने के लिए अपने ord() मूल्य

किस तरीके से बेहतर है के द्वारा? क्या आप इसे करने के बेहतर तरीके जानते हैं?

मुझे आशा है कि आप मेरी मदद कर सकते हैं। अग्रिम बहुत बहुत धन्यवाद!

+1

आप कोई अन्य, संभवतः प्रशिक्षु, मूल्य है अपने उपयोगकर्ताओं की पहचान करने के लिए? खैर, आपके पास अपनी उपयोगकर्ता तालिका के लिए कम से कम एक पीके होना चाहिए। – Malax

+0

@ मैलाक्स: हां, प्राथमिक कुंजी आईडी फ़ील्ड है जिसमें एमडी 5 हैश है। क्या यह एक बुरा समाधान है? – caw

+3

आपकी उपयोगकर्ता तालिका की प्राथमिक कुंजी के रूप में MD5 हैश का उपयोग करना आम तौर पर एक अच्छा विचार नहीं है। एक ऑटो-वृद्धि/सीरियल पूर्णांक आईडी 4-8 बाइट है। एक एमडी 5 हैश 32 बाइट्स है। पूर्णांक मानों पर तुलना (उदा।हर बार जब आप उस तालिका में शामिल होते हैं, या उससे एक पंक्ति चुनें) 32 बाइट तारों की तुलना में कई गुना तेज होगा, और पूर्णांक मानों को कम संग्रहण की आवश्यकता होगी। और वास्तव में ... यदि आप एक स्ट्रिंग मान का उपयोग करना चाहते हैं, तो ईमेल पते का उपयोग क्यों न करें? यह ज्यादातर समय 32 बाइट या उससे कम होने जा रहा है। –

उत्तर

16

सावधान रहें। MD5s को एक पूर्णांक में कनवर्ट करने के लिए बड़े (128-बिट) पूर्णांक के लिए समर्थन की आवश्यकता होगी। संभावना है कि आप जिस एपीआई का उपयोग कर रहे हैं वह केवल 32-बिट पूर्णांक का समर्थन करेगा - या इससे भी बदतर, फ्लोटिंग-पॉइंट में संख्या से निपट सकता है। किसी भी तरह से, आपकी आईडी मंग हो जाएगी। यदि ऐसा है, तो एमडी 5 को पूर्णांक में बदलने की कोशिश करने से चीजों से निपटने के लिए मनमाने ढंग से दूसरी आईडी असाइन करना एक बेहतर तरीका है।

हालांकि, अगर आप यकीन कि एपीआई मुसीबत के बिना मनमाने ढंग से बड़े पूर्णांकों के साथ सौदा कर सकते हैं, तो आप सिर्फ MD5 हेक्साडेसिमल से एक पूर्णांक के लिए बदल सकते हैं। PHP सबसे अधिक संभावना इस अंतर्निहित समर्थन का समर्थन नहीं करता है, क्योंकि यह इसे 32-बिट पूर्णांक या फ़्लोटिंग पॉइंट के रूप में प्रस्तुत करने का प्रयास करेगा; इसके लिए आपको शायद PHP GMP library का उपयोग करने की आवश्यकता होगी।

+3

+1 यह संकेत देने के लिए कि परिणामी मान एपीआई के लिए बहुत बड़ा हो सकता है, भले ही नंगे बाइट्स को पूर्णांक के रूप में उपयोग किया जाए। आपको अपने "ईमेल पते को पूर्णांक" -प्रोबलेम के लिए एक और समाधान मिलना चाहिए। – Malax

+0

बहुत बहुत धन्यवाद! क्या यह मेरे दो विचारों से बेहतर समाधान होगा? $ id_integer = base_convert ($ id_string, 16, 10); – caw

+0

base_convert के दस्तावेज़ों पर चेतावनी पढ़ें (http://www.php.net/manual/en/function.base-convert.php) - यह बड़ी संख्या के लिए उपयुक्त नहीं है। और एमडी 5 बहुत बड़ी संख्या में हैं। आप _must_ एक बड़ी लाइब्रेरी का उपयोग करते हैं, और जिस एपीआई को आप एक्सेस कर रहे हैं उसे भी ऐसा करना चाहिए - लेकिन मुझे संदेह है कि यह करता है। बस एक और कॉलम जोड़ें और प्रत्येक उपयोगकर्ता को मनमानी आईडी असाइन करें, यह बहुत आसान होगा। – bdonlan

1

आप hexdec का उपयोग हेक्साडेसिमल स्ट्रिंग पार्स और डेटाबेस में नंबर स्टोर करने के लिए कर सकता है।

+1

क्या यह 160-बिट पूर्णांक को मंग किए बिना संभालता है? – bdonlan

+2

उत्तर: नहीं, यह प्रलेखन के अनुसार, फ्लोट में परिवर्तित हो जाता है। तो आप डेटा के बारे में 120 बिट खो देंगे, और बाद में मूल MD5 को पुनर्प्राप्त करने में असमर्थ होंगे। – bdonlan

+2

आप सही हैं, एमडी 5 योग 32 बिट पूर्णांक के रूप में स्टोर करने के लिए बहुत बड़ा है। मेरे जवाब को अनदेखा करें। ;-) – Malax

1

क्या आप एक और फ़ील्ड जोड़ नहीं सकते जो एक ऑटो-इंक्रिमेंट इंटेल फ़ील्ड था?

1

क्यों ord()? md5 सामान्य 16-बाइट मान उत्पन्न करता है, जो आपको बेहतर पठनीयता के लिए हेक्स में प्रस्तुत करता है। तो आप नुकसान के बिना 16-बाइट मान 4 या 8 बाइट पूर्णांक में परिवर्तित नहीं कर सकते हैं। आईडी के रूप में इसका उपयोग करने के लिए आपको अपने एल्गोरिदम के कुछ हिस्से को बदलना होगा।

+0

एमडी 5 एक 20-बाइट मूल्य पैदा करता है। – bdonlan

+2

हममम ... हो सकता है मैं पूरी तरह से मूर्ख हूँ लेकिन ... fred @ fred-डेस्कटॉप: ~ $ md5sum citycode.sql 734e4d6f039a81c8a196db588e1cb002 citycode.sql 73 4e 4d 6F 03 9a 81 सी 8 a1 96 db 58 8e 1c B0 02 यहाँ एक marco92w (प्रश्न मालिक) मूल्य d4 1 दिन 8C d9 8F 00 b2 04 E9 80 09 98 ईसी F8 42 7e क्या गलत है मेरे साथ? अतिरिक्त बाइट्स कहां है? –

+0

@ बोडनान: नहीं, 128 बिट्स 16 बाइट्स के बराबर है, है ना? – caw

10

दूसरों द्वारा बताए गए अच्छे कारण हैं, इसे अलग तरीके से करने के लिए।

लेकिन क्या आप क्या करना चाहते एक स्ट्रिंग दशमलव अंक की में एक MD5 हैश कन्वर्ट (जो कि मैं क्या लगता है कि आप वास्तव में से मतलब है "एक पूर्णांक द्वारा प्रतिनिधित्व", के बाद से एक md5 पहले से ही एक पूर्णांक है है अगर स्ट्रिंग फार्म), में है और इसे वापस बदलना ही md5 स्ट्रिंग में:

function md5_hex_to_dec($hex_str) 
{ 
    $arr = str_split($hex_str, 4); 
    foreach ($arr as $grp) { 
     $dec[] = str_pad(hexdec($grp), 5, '0', STR_PAD_LEFT); 
    } 
    return implode('', $dec); 
} 

function md5_dec_to_hex($dec_str) 
{ 
    $arr = str_split($dec_str, 5); 
    foreach ($arr as $grp) { 
     $hex[] = str_pad(dechex($grp), 4, '0', STR_PAD_LEFT); 
    } 
    return implode('', $hex); 
} 

डेमो:

$md5 = md5('[email protected]'); 
echo $md5 . '<br />'; // 23463b99b62a72f26ed677cc556c44e8 
$dec = md5_hex_to_dec($md5); 
echo $dec . '<br />'; // 0903015257466342942628374306682186817640 
$hex = md5_dec_to_hex($dec); 
echo $hex;    // 23463b99b62a72f26ed677cc556c44e8 
बेशक

, आप caref होना होगा उल या तो स्ट्रिंग का उपयोग, उन्हें केवल स्ट्रिंग प्रकार के रूप में उपयोग करने के लिए अग्रणी शून्य को खोने से बचने के लिए सुनिश्चित कर रही है की तरह है, यह सुनिश्चित तार सही लंबाई हैं आदि

+0

बहुत बहुत धन्यवाद। इस तरह यह काम करेगा। लेकिन अब मैं देख सकता हूं कि अन्य सभी क्या कहना चाहते थे: नया पूर्णांक बहुत लंबा है। और अग्रणी शून्य भी एक समस्या है। – caw

+0

मदद करने के लिए खुशी हुई।ध्यान रखें कि दशमलव अंक स्ट्रिंग और हेक्स अंक स्ट्रिंग (md5 स्ट्रिंग) गणितीय के बराबर नहीं हैं; वे इन साथी कार्यों द्वारा उत्पादित एक दूसरे के केवल "अनुवाद" हैं, जो उनके संबंधित अंक प्रतीक सेट में हैं। – GZipp

1

किस बारे में:

$ नाव = hexdec (md5 (' स्ट्रिंग '));

या

$ पूर्णांक = (पूर्णांक) (substr (hexdec (md5 ('स्ट्रिंग')), 0,9) * 100000000);

टक्कर के लिए निश्चित रूप से बड़ी संभावनाएं हैं लेकिन फिर भी डीबी में हैश के बजाय उपयोग करने के लिए अच्छा लगा है?

चियर्स,

/मार्सिन

+0

यह एक भी बेहतर है: sprintf ("% u", crc32 (md5 ('string'))); – Marcin

+0

अच्छी तरह से lemme 32 * 16 बिट की गणना ... आप 64bytes की नींव रखेंगे। किसी भी फ्लोट या लंबे समय तक डबल;) आपकी संख्या छिड़काव या गोलाकार द्वारा सटीक खो देंगे –

0

उपयोग किसी साझा फ़ोल्डर में एक खाली, अस्थायी फ़ाइल का फ़ाइल नाम के रूप में ईमेल पते, जैसे /var/myprocess/[email protected]

फिर, फ़ाइल नाम पर ftok कॉल करें। ftok एक अद्वितीय, पूर्णांक आईडी लौटाएगा।

हालांकि यह अद्वितीय होने की गारंटी नहीं दी जाएगी, लेकिन यह शायद आपके एपीआई के लिए पर्याप्त होगी।

6

32-बिट संघनन के लिए, एमडी 5 हैश के 4 हेक्स जोड़े (8 वर्ण) का चयन करके एक साधारण समाधान किया जा सकता है, जहां प्रत्येक जोड़ी एक बाइट का प्रतिनिधित्व करती है, और फिर intval() के साथ परिवर्तित कर देती है।

एक अहस्ताक्षरित 32-बिट इंट के लिए:

$inthash = intval(substr(md5($str), 0, 8), 16); 

केवल एक हस्ताक्षरित 32-बिट इंट के सकारात्मक मूल्य के लिए:

$inthash = intval(substr(md5($str), 0, 8), 16) >> 1; 

यह संभावना केवल 64 अप करने के लिए मूल्यों के लिए काम करेंगे दस्तावेज़ों में उल्लेख किए गए अधिकांश आधुनिक प्रणालियों के लिए बिट (8 बाइट्स या 16 वर्ण)।

एक प्रणाली है कि 64-बिट Ints, एक बंटवारे रणनीति है कि खपत 2 Ints के रूप में पूरे 128 बिट MD5 हैश लग सकता है की तरह समायोजित कर सकते हैं पर:

$hash = md5($str); 
$inthash1 = intval(substr($hash, 0, 16), 16); 
$inthash2 = intval(substr($hash, 16, 16), 16); 
संबंधित मुद्दे