2010-08-06 22 views
6

मुझे लिंक जैसे छोटे यूआरएल बनाने में दिलचस्पी है। मेरा विचार बस हर लंबे यूआरएल पोस्ट के लिए एक बढ़ाने पहचानकर्ता को संग्रह करने और फिर इसे का आधार 36 संस्करण इस आईडी परिवर्तित, पीएचपी में निम्नलिखित की तरह था:आईडी पर आधारित "छोटे यूआरएल" को कैसे उत्पन्न किया जाए?

$tinyurl = base_convert($id, 10, 36) 

समस्या है कि यहाँ परिणाम अनुमान लगाया जा सकता है, जबकि यह यह अनुमान लगाने में कठिनाई होनी चाहिए कि अगला यूआरएल क्या होगा, जबकि अभी भी छोटा (छोटा) है। उदाहरण के लिए। एटीएम अगर मेरा आखिरी टिन्यूरल ए 1 था, तो अगला वाला ए 2 होगा। यह मेरे लिए एक बुरी बात है।

तो, मैं कैसे सुनिश्चित करूँगा कि परिणामस्वरूप छोटे यूआरएल अनुमानित नहीं हैं लेकिन अभी भी कम हैं?

उत्तर

9

जो आप पूछ रहे हैं वह जानकारी की कमी (आपके डेटाबेस में उनके सूचकांक में यूआरएल), और कृत्रिम वृद्धि (आपके अनुक्रम में छेद बनाने के लिए) के बीच संतुलन है।

आपको यह तय करना होगा कि आपके लिए दोनों कितने महत्वपूर्ण हैं। एक और सवाल यह है कि क्या आप अनुक्रमिक यूआरएल अनुमान लगाने योग्य नहीं चाहते हैं, या अनुमानित मान्य यूआरएल मुश्किल बनाने के लिए पर्याप्त रूप से यादृच्छिक हैं।

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

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

+0

। मुझे लगता है कि वह एक मूल्य चाहता है जो वह विपरीत हो सकता है, यानी, वह एक इंजेक्शन समारोह चाहता है। – Artefacto

+1

नहीं, वह वास्तव में एक असहनीय समारोह चाहता है। ;) चूंकि उसे किसी भी डेटाबेस में यूआरएल स्टोर करना है, तो वह यादृच्छिक संख्या को इंडेक्स के रूप में उपयोग कर सकता है। रिवर्सल हासिल किया। – relet

+0

सच है, इंजेक्शन नहीं होना चाहिए। – Tom

5

मैं करूंगा बस CRC32 यूआरएल

$url = 'http://www.google.com'; 
$tinyurl = hash('crc32', $url); // db85f073 

विपक्ष: लगातार 8 वर्ण लंबे पहचानकर्ता

+0

मैं इस विचार को पसंद है, लेकिन 8-चरित्र कोड एक समस्या की तरह है - URL शॉर्टनर इन दिनों, हर चरित्र की गिनती के साथ, और 8 एक छोटे से अधिक है। –

4

यह वास्तव में सस्ता है, लेकिन अगर उपयोगकर्ता यह क्या हो रहा है पता नहीं है तो यह के रूप में अनुमान लगाया जा सकता नहीं है, लेकिन उपसर्ग और वास्तविक आईडी को 2 या 3 यादृच्छिक संख्या/अक्षरों के साथ पोस्टफिक्स करें।

यदि मैंने 9 डी 2 ए 1 ​​एम 3 देखा तो मुझे लगता है कि डीएम 2 ए 2 डीक्यू 2 श्रृंखला में अगला नहीं था।

2

कुछ मूल्य के साथ $ id Xor'ing आज़माएं, उदा। $id^46418 - और अपनी मूल आईडी में वापस कनवर्ट करने के लिए आप एक ही एक्सर फिर से करते हैं i.e. $mungedId^46418। इसे अपने बेस_कॉन्टर के साथ एक साथ ढेर करें और परिणामस्वरूप स्ट्रिंग में वर्णों के कुछ स्वैपिंग और यूआरएल अनुमान लगाने में काफी मुश्किल हो जाएगी।

+0

यह तोड़ना बहुत आसान है। – Artefacto

+0

थोड़ा निर्धारित हैकर सुनिश्चित करने के लिए - जो जनता के लिए, इतना नहीं। आपके पिछले पैराग्राफ के बारे में –

0

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

+0

हालांकि, यह स्केल नहीं करता है। – relet

+1

मुझे यह इंगित करना चाहिए कि यह एक यूआरएल शॉर्टनर के लिए मैंने किया है, और यह शुरू करने के लिए दर्द का थोड़ा सा है। बहुत सारे संभावित संयोजन हैं, जिसका अर्थ है कि आप इस तरह की एक सरल अवधारणा के लिए एक विशाल डेटाबेस फ़ाइल के साथ शुरू करते हैं। –

+0

@relet आप वास्तव में क्या कह रहे हैं? तथ्य यह है कि एक सीमित संख्या है जो बढ़ नहीं सकती है? यदि ऐसा है, तो एक बार जब आप 4-वर्ण कोड से बाहर निकलना शुरू कर देते हैं, तो सभी 5-वर्ण कोडों की गणना करें और अपनी कतार तालिका में डालें। –

1

यदि आप इंजेक्शन फ़ंक्शन चाहते हैं, तो आप किसी भी प्रकार के एन्क्रिप्शन का उपयोग कर सकते हैं।उदाहरण के लिए:

<?php 
$key = "my secret"; 
$enc = mcrypt_ecb (MCRYPT_3DES, $key, "42", MCRYPT_ENCRYPT); 
$f = unpack("H*", $enc); 
$value = reset($f); 
var_dump($value); //string(16) "1399e6a37a6e9870" 

उल्टा करने के लिए:

$rf = pack("H*", $value); 
$dec = rtrim(mcrypt_ecb (MCRYPT_3DES, $key, $rf, MCRYPT_DECRYPT), "\x00"); 
var_dump($dec); //string(2) "42" 

यह आपको आधार 32 में एक नंबर नहीं देंगे; यह आपको एन्क्रिप्टेड डेटा देगा जिसमें प्रत्येक बाइट बेस 16 में परिवर्तित हो जाएगा (यानी, रूपांतरण वैश्विक है)। यदि आपको वास्तव में आवश्यकता है, तो आप बड़े पैमाने पर पूर्णांक का समर्थन करने वाली किसी लाइब्रेरी के साथ इसे आधार 10 में परिवर्तित कर सकते हैं और फिर बेस 32 पर कर सकते हैं।

+0

ध्यान रखें कि परिणामी यूआरएल छोटा होना चाहिए (1399e6a37a6e9870 बहुत लंबा है)। – Tom

+0

@ टॉम वेल, वह इसे 64 या उससे अधिक आधार में परिवर्तित कर सकता है और मुझे लगता है (मुझे लगता है) 11 अक्षर। या – Artefacto

2

यूआरएल के लिए अधिकतम संख्या में वर्ण सेट करना होगा (मान लें कि यह n है)। फिर आप 1 और एन के बीच यादृच्छिक संख्या चुन सकते हैं, जो आपका क्रमपरिवर्तन संख्या होगा।

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

+0

का उपयोग करें डुप्लिकेट आईडी इस तरह से संभव है, इसलिए आपको डुप्लिकेट होने पर उसे जांचना होगा और फिर से वृद्धि करना होगा। – Tom

+0

@ टॉम नहीं, वे नहीं ... – Artefacto

-1

मैंने पहचानकर्ता का एमडी 5 योग तैयार किया, इसके पहले 4 अल्फान्यूमेरिक्स का उपयोग किया और यदि यह एक डुप्लिकेट है तो लंबाई को बढ़ाएं जब तक कि यह अब डुप्लिकेट न हो।

function idToTinyurl($id) { 
    $md5 = md5($id); 
    for ($i = 4; $i < strlen($md5); $i++) { 
     $possibleTinyurl = substr($md5, 0, $i); 
     $res = mysql_query("SELECT id FROM tabke WHERE tinyurl='".$possibleTinyurl."' LIMIT 1"); 
     if (mysql_num_rows($res) == 0) return $possibleTinyurl; 
    } 
    return $md5; 
} 

स्वीकार्य रीलेट का जवाब क्योंकि यह मुझे इस रणनीति में ले जाता है।

0

Hashids एक ओपन-सोर्स लाइब्रेरी है जो छोटी, अद्वितीय, गैर अनुक्रमिक, YouTube जैसी आईडी उत्पन्न करता है जो एक या कई संख्याओं से होता है। आप इसे पर obfuscate करने के लिए एक एल्गोरिदम के रूप में सोच सकते हैं।

यह 347 जैसे तारों को "yr8", या सरणी [27, 9 86] जैसे "3kTMd" में परिवर्तित करता है। आप उन आईडी को वापस डीकोड भी कर सकते हैं। यह कई मानकों को बंडल करने में उपयोगी है या उन्हें कम यूआईडी के रूप में उपयोग कर रहा है।

इसका इस्तेमाल जब आप उपयोगकर्ता के लिए अपने डेटाबेस आईडी बेनकाबनहीं करना चाहती।

यह कस्टम वर्णमाला के साथ ही नमक की अनुमति देता है, इसलिए आईडी केवल आपके लिए अद्वितीय हैं।

वृद्धिशील इनपुट को अव्यवस्थित रहने के लिए उलझाया गया है।

कोई टक्कर नहीं है क्योंकि यह विधि हेक्स रूपांतरण के पूर्णांक पर आधारित है।

यह यूआरएल की तरह दृश्यमान स्थानों में बनाई गई आईडी को रखने के इरादे से लिखा गया था। इसलिए, एल्गोरिदम सबसे आम अंग्रेजी शाप शब्दों को उत्पन्न करने से बचाता है।

कोड उदाहरण

$hashids = new Hashids(); 
$id = $hashids->encode(1, 2, 3); // o2fXhV 
$numbers = $hashids->decode($id); // [1, 2, 3]