2010-09-27 10 views
6

मैं खुद को एक स्क्रिप्ट लिख रहा हूं जो मूल रूप से मुझे एक ही अनुरोध के क्वेरीस्ट्रिंग में एक यूआरएल और दो पूर्णांक आयाम भेजने देता है। मैं इसे एन्कोड करने के लिए बेस 64 का उपयोग कर रहा हूं, लेकिन यह बहुत लंबा है और मुझे चिंता है कि यूआरएल बहुत बड़ा हो सकता है।PHP: किसी अन्य यूआरएल में एम्बेडेड यूआरएल के लिए छोटा/अस्पष्ट एन्कोडिंग?

क्या कोई इसे करने का वैकल्पिक, छोटा तरीका जानता है? प्राप्त अनुरोध में प्राप्त होने पर इसे डीकोड-सक्षम होने की आवश्यकता होती है, इसलिए md5/sha1 संभव नहीं है।

आपके समय के लिए धन्यवाद।


संपादित क्षमा करें - मैं बेहतर समझा दिया है चाहिए: ठीक है, हमारी साइट पर उन वेबसाइटों को समीक्षा के लिए ऊपर के पोस्ट होने के स्क्रीनशॉट प्रदर्शित करते हैं। हमारे पास अपना स्वयं का थंबनेल/स्क्रीनशॉट सर्वर है। मैं मूल रूप से छवि टैग होने वाला एक एन्कोडेड स्ट्रिंग रखता हूं जो यूआरएल को स्क्रीनशॉट लेने के लिए स्टोर करता है, और छवि की चौड़ाई/ऊंचाई दिखाने के लिए। हालांकि मैं इसे देखने के लिए 'कच्चे-पाठ' में नहीं चाहता हूं। स्पष्ट रूप से बेस 64 किसी के द्वारा तय किया जा सकता है, लेकिन हम नहीं चाहते हैं कि आपका औसत जो यूआरएल पथ उठा रहा हो। वास्तव में मुझे एक जीईटी अनुरोध में यूआरएल, चौड़ाई, ऊंचाई लाने की जरूरत है।

+2

क्या कोई विशेष कारण है कि पोस्ट या सत्र का उपयोग न करें? वे पृष्ठ –

+0

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

+0

मैं उलझन में हूँ। क्या आप सर्वर से या ब्राउज़र से छवि भेज रहे हैं? –

उत्तर

3

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


संपादित करें: मैं एक बात समझ में नहीं आता। आप स्क्रीन शॉट्स कैश क्यों नहीं कर रहे हैं? ऐसा लगता है कि जब भी कोई व्यक्ति उस यूआरएल के आईएमजी लिंक के साथ किसी पृष्ठ को देखता है तो एक नया स्क्रीनशॉट लेना बहुत गहन संसाधन लगता है।

शायद आपके दर्शक छोटे हैं, और संसाधन एक मुद्दा नहीं हैं। हालांकि, अगर यह विपरीत है और वास्तव में यह एक सार्वजनिक वेबसाइट है-जो बहुत अच्छी तरह से स्केल नहीं करेगा। मुझे पता है कि मैं आपके मूल प्रश्न से क्या आगे बढ़ रहा हूं, लेकिन यह आपके प्रश्न और अधिक हल करेगा।

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

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

या, बस आसान तरीका लेने के लिए और यह base64_encode($whole_file) करते http://www.snap.com/

+0

क्वेरीस्ट्रिंग के साथ REST-ish webservices निश्चित रूप से बैक-एंड और HTTP कैशिंग लागू कर सकते हैं। जैसे Google का चार्ट एपीआई –

+2

प्रश्न का उत्तर देने के लिए यह एक शानदार तरीका है, अच्छी तरह से किया गया। – Deji

1

बस के साथ ग्राहक के पक्ष ऐसा नहीं। सामग्री में भाग भेजें और भाग को एन्कोड करें। इसके अलावा, आप, पता होना चाहिए कि कैसे बड़ा अपने हिस्सा base64_encode() के लिए एक कॉल के बाद प्राप्त कर सकते हैं यह होगा और अधिक से अधिक आकार में डबल (लेकिन कम से कम 2.1*strlen($chunk))

+2

यदि आप पीछे की पैडिंग जोड़ते हैं तो अनुपात 4/3, या 4 · छत (एन/3) है। – Gumbo

1

तुम अब भी क्या आप यह सोचते हैं का वर्णन मैं अपने को सही ढंग से समझ में आ के लिए पोस्ट का उपयोग कर सकते हैं, मेरे पास नहीं हो सकता है

<a href="scripturl?w=11&h=100&url=really-long-secret-base64"> 
    <img src="imgurl"> 
</a> 

बजाय कुछ इस तरह करते हैं:

मैं तुम्हें कुछ इस तरह कर रहे हैं अनुमान लगा रहा हूँ

<form method="POST" action="scripturl"> 
    <input type="hidden" name="width" value="100"> 
    <input type="hidden" name="height" value="100"> 
    <input type="hidden" name="url" value="secret-url-string-here"> 
    <input type="image" src="imgurl" name="submit"> 
</form> 
0

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

5

चूंकि आप केवल स्ट्रिंग को obfuscate करने के लिए बेस 64 का उपयोग कर रहे हैं, तो आप इसे रोट 13 (या अपने स्वयं के साधारण अक्षर प्रतिस्थापन समारोह) जैसे किसी अन्य चीज़ के साथ खराब कर सकते हैं। इसलिए, urlencode(str_rot13($str)) एन्कोड करने के लिए और str_rot13(urldecode($str)) को डीकोड करने के लिए।

या, केवल एक छोटा बेस 64-एन्कोडेड स्ट्रिंग होने के लिए, आप बेस 64 एन्कोडिंग से पहले स्ट्रिंग को संकुचित कर सकते हैं: base64_encode(gzencode($str, 9)) और gzdecode(base64_decode($str)) डीकोड करने के लिए।

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

function getHash($url, $width, $height) { 
    $secret = 'abcdefghijklmnopqrstuvwxyz whatever you want etc.'; 
    return sha1($url . $width . $height . $secret); 
} 

// So use this hash to to construct your URL querystring: 
$hash = getHash($url, $width, $height); 
$urlQuerystring = '?url='.urlencode($url).'&width='.(int) $width. 
        '&height='.(int) $height.'&hash='.$hash; 

// Then in your code that processes the URL, check the hash first 
if ($hash != getHash($url, $width, $height)) 
    // URL is invalid 

(विषय बंद:। लोग कह रहे हैं आप प्राप्त करने के बजाय पोस्ट का उपयोग करना चाहिए इन सभी यूआरएल कर रहे हैं प्रदर्शित करने के लिए (यानी एक खोज देखने अपने डेटाबेस से स्क्रीनशॉट प्राप्त करने में कठिनाई है) तब मिलता है ठीक है और सही है। लेकिन अगर इन यूआरएल को कॉल करना वास्तव में स्क्रीनशॉट बनाने और संग्रहीत करने जैसी दूसरी साइट पर जा रहा है, तो यह एक पोस्ट है। जैसा कि उनके नाम बताते हैं, जीईटी पुनर्प्राप्ति के लिए है; POST डेटा जमा करने के लिए है। अगर आप का उपयोग करना है स्क्रीनशॉट बनाने जैसे महंगे ऑपरेशन पर जाएं, जब आप Google आदि इन यूआरएल को इंडेक्स करते हैं तो आप अपनी साइट को डॉसिंग कर सकते हैं।)

2

ऐसा लगता है कि आपके लक्ष्य 1. से दृश्यमान रूप से एक यूआरएल अस्पष्ट हैं, और 2. आमतौर पर URL में उपयोग के लिए कॉम्पैक्टली डेटा को एन्कोड करें।

सबसे पहले, हमें URL को अस्पष्ट करने की आवश्यकता है। चूंकि यूआरएल बेस 64 डिक्शनरी का अधिक उपयोग करते हैं, इसलिए कोई भी एन्कोडिंग जो बाइनरी उत्पन्न करती है (जो तब बेस 64-एड होना चाहिए) शायद आकार को बढ़ाएगी। urlencode() लागू होने पर बचने के लिए न्यूनतम आवश्यकता के साथ शब्दकोश को यूआरएल-सुरक्षित श्रेणी में रखना सबसे अच्छा है। अर्थात।

/** 
* Rot35 for URLs. To avoid increasing size during urlencode(), commonly encoded 
* chars are mapped to more rarely used chars (end of the uppercase alpha). 
* 
* @param string $url 
* @return string 
*/ 
function rotUrl($url) { 
    return strtr($url, 
     'abcdefghijklmnopqrstuvwxyz0-:/?=&%#123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
     '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0-:/?=&%#'); 
} 

अब, बाइट्स को बचाने के लिए, हम यूआरएल स्कीमा एक चार में सांकेतिक शब्दों में बदलना कर सकते हैं (जैसे कि, HTTPS के लिए HTTP के लिए h, H), और आधार में आयाम परिवर्तित 32. रैपिंग इस अप: यदि आप इस हैं:

function obscure($width, $height, $url) { 
    $dimensions = base_convert($width, 10, 32) . "." 
       . base_convert($height, 10, 32) . "."; 
    preg_match('@^(https?)://(.+)@', $url, $m); 
    return $dimensions . (($m[1] === 'http') ? 'h' : 'H') . rotUrl($m[2]); 
} 

function unobscure($str) { /* exercise for the reader! */ } 

$url = 'https://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=Base64'; 
$obs = obscure(550, 300, $url); 
// h6.9c.H5E.N9B9G5491.FI7UNU9E45O.G8GVK9KC5W-G5391CYcj-51I38XJ51I38Wk1J5fd 

चूंकि हम गैर यूआरएल-सुरक्षित वर्ण से बचा, अगर यह (urlencode साथ) एक क्वेरी स्ट्रिंग में डाल रहा है, यह भी नहीं बढ़ता है बहुत (इस मामले में बिल्कुल नहीं)।

इसके अतिरिक्त आप इस स्ट्रिंग पर हस्ताक्षर करना चाहेंगे ताकि लोग जो एन्कोडिंग को जानते हों वे अभी भी यूआरएल के माध्यम से अपने पैरामीटर निर्दिष्ट नहीं कर सकते हैं। इसके लिए आप HMAC का उपयोग करेंगे, और बेस 64URL-हैश एन्कोड करें। आप अंतरिक्ष को बचाने के लिए हैश (~ 6 बिट प्रति चरित्र) के एक सबस्ट्रिंग को भी रख सकते हैं।

function sign($key, $data) { 
    return $data . _hmac($key, $data, 8); 
} 
function verify($key, $signed) { 
    $mac = substr($signed, -8); 
    $data = substr($signed, 0, -8); 
    return $mac === _hmac($key, $data, 8) ? $data : false; 
} 
function _hmac($key, $data, $macLength) { 
    $mac = substr(base64_encode(hash_hmac('sha256', $data, $key, true)), 0, $macLength); 
    return strtr($mac, '+/', '-_'); // for URL 
} 

$key = "Hello World!"; 
$signed = sign($key, $obs); // appends MAC: "w-jjw2Wm" 

$obs = verify($key, $signed); // strips MAC and returns valid data, or FALSE 

अपडेट:: एक बेहतर RotURL functionsign() (नीचे) एक 8 चरित्र मैक (6 बिट्स/चार पर हैश के 48 बिट) कहते हैं।

+0

यह एकमात्र 'उत्तर' है। अन्य उत्तरों सुरक्षा पर तय करते हैं जो पूछताछकर्ता ने विशेष रूप से कहा महत्वपूर्ण नहीं था, या केवल सवाल के खिलाफ बहस करने का प्रयास करें। हालांकि, यह उत्तर उन लोगों के लिए उपयोगी है जो इस विशिष्ट प्रश्न की तलाश में आते हैं। – Deji

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