अंडरहेड पासवर्ड हैशिंग [बंद]


33

अंडरहैंड सी प्रतियोगिता की भावना में , मैं एक अंडरहैंड कोड प्रतियोगिता शुरू कर रहा हूं। इस प्रतियोगिता का उद्देश्य सीधे तौर पर कुछ कोड को लागू करना है, जबकि इसके अंदर एक नापाक बग को छिपाना है।

प्रतियोगिता

आप एक गुप्त रूसी तिल हैं जो एक अमेरिकी जासूस एजेंसी के आईटी विभाग में काम कर रहे हैं। आपके अमेरिकी बॉस ने आपको गुप्त संदेशों को एन्क्रिप्ट करने के लिए उपयोग करने के लिए पासवर्ड हैशिंग एल्गोरिथ्म को लागू करने के लिए कहा है।

आपका बॉस चाहता है कि आप निम्नलिखित फ़ंक्शन को लागू करें:

f: String -> byte[16]

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

बेशक, रूसी जासूसी एजेंसी में आपका असली मालिक आपको इस प्रक्रिया से वंचित करना चाहेगा। आपका कार्य fइस तरह लागू करना है कि रूसियों द्वारा लौटाए गए कुंजी का उपयोग करके एन्क्रिप्ट किए गए सभी गुप्त संदेशों को डिक्रिप्ट कर सकते हैं f

ऐसा करने के लिए, आपको इसे लागू करना होगा fताकि यह केवल 2 ^ 128 संभावित आउटपुट के एक छोटे उपसमूह को लौटाए। विशेष रूप से, आपका fअधिकतम 2 ^ 16 विभिन्न परिणामों पर वापस लौटना चाहिए ताकि रूसी वे एन्क्रिप्ट किए गए प्रत्येक एन्क्रिप्ट किए गए संदेश के लिए सही कुंजी के लिए एक आसान जानवर-बल खोज कर सकें।

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

आंकना

मैं और मेरे द्वारा भर्ती किए गए दो अन्य लोग प्रविष्टियों का न्याय करेंगे (यदि आप न्यायाधीश चाहते हैं तो मुझे ईमेल करें)। मैं जीतने वाली प्रविष्टि के लिए 200 प्रतिष्ठा इनाम की पेशकश कर रहा हूं। सबमिशन 1 मई तक अपलोड करना होगा।

निम्नलिखित मानदंडों को ध्यान में रखते हुए:

  • fकल्पना का पालन करता है , अर्थात यह 2 ^ 8 और 2 ^ 16 संभावित आउटपुट के बीच उत्पन्न करता है। यह महसूस न करें कि ये कठिन सीमाएँ हैं, लेकिन यदि आप बहुत अधिक सीमा से बाहर हैं तो हम अंक काट लेंगे।
  • क्या बग अनजाने में हुई गलती का परिणाम है?
  • fयादृच्छिक देखो के आउटपुट करते हैं ?
  • आपका कार्यान्वयन जितना छोटा होगा f, उतना अच्छा होगा।
  • आपका कार्यान्वयन जितना स्पष्ट होगा f, उतना अच्छा होगा।

टिप्पणियाँ

अपने कोड को लागू करने के लिए आप किसी भी भाषा का उपयोग कर सकते हैं। आप सादे दृष्टि में एक बग को छिपाने की कोशिश कर रहे हैं, इसलिए बाधित कोड का सुझाव नहीं दिया गया है।

आप पिछले अंडरहैंड सी प्रतियोगिता के विजेताओं में से कुछ पर एक नज़र डालना चाहते हैं जो एक अच्छा सबमिशन बनाता है।

इनपुट स्ट्रिंग्स मुद्रण योग्य अस्की (126 के माध्यम से 32, समावेशी) होंगे। आप चाहें तो एक उचित अधिकतम लंबाई मान सकते हैं।


1
क्या इनपुट स्ट्रिंग पर कोई सीमा है? जैसे यह केवल वर्णमाला से बना है?
अली 1 एस 232

@ गजेत: आपको सभी प्रिंट करने योग्य अस्की चरित्र (32 126, समावेशी के माध्यम से) को संभालना होगा।
कीथ रान्डेल

क्या आउटपुट रेंज सभी 16-बाइट स्ट्रिंग्स, या सिर्फ प्रिंट करने योग्य हैं?
बूथ

@boothby: सभी संभव 16-बाइट मान (2 ^ 128 संभावनाएं)
कीथ रान्डेल

1
मैं इस प्रश्न को ऑफ़-टॉपिक के रूप में बंद करने के लिए मतदान कर रहा हूँ क्योंकि इस साइट पर अंडरहैंड चुनौतियाँ अब ऑन-टॉपिक नहीं हैं। meta.codegolf.stackexchange.com/a/8326/20469
बिल्ली

जवाबों:


15

सी

2 ^ 16 संभावित आउटपुट (या 2 ^ 8 बार उपयोग किए गए वर्णों की संख्या)।
लिनक्स के MD5 कार्यान्वयन का उपयोग करता है, जो कि AFAIK, ठीक है। लेकिन यह वही हैश देता है, उदाहरण के लिए, "40" और "42" के लिए।
संपादित करें: नाम बदलकर bcopyकरने के लिए memcpy(बेशक बदली पैरामीटर)।
संपादित करें: आवश्यकताओं को बेहतर तरीके से पूरा करने के लिए कार्यक्रम से कार्य में परिवर्तित।

#include <string.h>
#include <openssl/md5.h>

void f(const unsigned char *input, unsigned char output[16]) {

    /* Put the input in a 32-byte buffer, padded with zeros. */
    unsigned char workbuf[32] = {0};
    strncpy(workbuf, input, sizeof(workbuf));

    unsigned char res[MD5_DIGEST_LENGTH];
    MD5(workbuf, sizeof(workbuf), res);

    /* NOTE: MD5 has known weaknesses, so using it isn't 100% secure.
     * To compensate, prefix the input buffer with its own MD5, and hash again. */
    memcpy(workbuf+1, workbuf, sizeof(workbuf)-1);
    workbuf[0] = res[0];
    MD5(workbuf, sizeof(workbuf), res);

    /* Copy the result to the output buffer */
    memcpy(output, res, 16);
}

/* Some operating systems don't have memcpy(), so include a simple implementation */
void *
memcpy(void *_dest, const void *_src, size_t n)
{
    const unsigned char *src = _src;
    unsigned char *dest = _dest;
    while (n--) *dest++ = *src++;
    return _dest;
}

यह एमडी 5 के साथ एक दोष है?
अली

@ गजेट, नहीं, मैंने लिनक्स के एमडी 5 का उपयोग किया, जो पूरी तरह से ठीक है (एएफएआईके)।
११:

वे क्यों यह अधिक संभव उत्पादन उत्पन्न नहीं करता है?
अली

1
@ गजेट: गौर कीजिए कि bcopyस्टेप में क्या होता है ... यह गलत मिसाल है , क्योंकि वास्तविक बीएसडी bcopyफंक्शन यहां ठीक से काम करेगा।
हान

@han, वास्तव में, अब मैं देख रहा हूं कि मेरी bcopyछोटी गाड़ी है। मैं इसे बदल दूंगा memcpy, और फिर वही कार्यान्वयन मान्य हो जाएगा।
ugoren

13

सी

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

#include <stdio.h>
#include <string.h>
#include <stdint.h>

void hash(const char* s, uint8_t* r, size_t n)
{
     uint32_t h = 123456789UL;
     for (size_t i = 0; i < n; i++) {
          for (const char* p = s; *p; p++) {
               h = h * 33 + *p;
          }
          *r++ = (h >> 3) & 0xff;
          h = h ^ 987654321UL;
     }
}

int main()
{
     size_t n = 1024;
     char s[n];
     size_t m = 16;
     uint8_t b[m];
     while (fgets(s, n, stdin)) {
          hash(s, b, m);
          for (size_t i = 0; i < m; ++i)
               printf("%02x", b[i]);
          printf("\n");
     }
}

वास्तव में हैश फ़ंक्शन L * 2048 से अधिक भिन्न परिणाम नहीं दे सकता है, जहाँ L विभिन्न इनपुट स्ट्रिंग लंबाई की संख्या हो सकती है। व्यवहार में, मैंने अपने लैपटॉप पर मैनुअल पेज और HTML दस्तावेजों से 1.85 मिलियन अद्वितीय इनपुट लाइनों पर कोड का परीक्षण किया, और केवल 85428 अलग-अलग अद्वितीय हैश मिला।


0

स्काला:

// smaller values for more easy tests:
val len = 16
// make a 16 bytes fingerprint
def to16Bytes (l: BigInt, pos: Int=len) : List[Byte] = 
  if (pos == 1) List (l.toByte) else (l % 256L).toByte :: to16Bytes (l / 256L, pos-1)
/** if number isn't prime, take next */
def nextProbPrime (l: BigInt) : BigInt = 
  if (l.isProbablePrime (9)) l else nextProbPrime (l + 1)
/** Take every input, shift and add, but take primes */
def codify (s: String): BigInt = 
  (BigInt (17) /: s) ((a, b) => nextProbPrime (a * BigInt (257) + b))
/** very, very short Strings - less than 14 bytes - have to be filled, to obscure them a bit: */
def f (s: String) : Array [Byte] = {
  val filled = (if (s.size < 14) s + "secret" + s else s)
  to16Bytes (codify (filled + filled.reverse)).toArray.map (l => nextProbPrime (l).toByte) 
}

परीक्षण, यदि परिणाम समान इनपुट के लिए समान नहीं दिखता है:

val samples = List ("a", "aa", "b", "", "longer example", "This is a foolish, fishy test") 

samples.map (f) 

 List[Array[Byte]] = List(
Array (-41, -113, -79, 127, 29, 127, 31, 67, -19, 83, -73, -31, -101, -113, 97, -113), 
Array (-19, 7, -43, 89, -97, -113, 47, -53, -113, -127, -31, -113, -67, -23, 127, 127), 
Array (-41, -113, -79, 127, 29, 127, 31, 67, -19, 83, -73, -31, -101, -113, 97, -113), 
Array (37, -19, -7, 67, -83, 89, 59, -11, -23, -47, 97, 83, 19, 2, 2, 2), 
Array (79, 101, -47, -103, 47, -13, 29, -37, -83, -3, -37, 59, 127, 97, -43, -43), 
Array (37, 53, -43, -73, -67, 5, 11, -89, -37, -103, 107, 97, 37, -71, 59, 67))

त्रुटि एन्कोडिंग के लिए सिर्फ primes का उपयोग कर रहा है। के बजाय

scala> math.pow (256, 16)
res5: Double = 3.4028236692093846E38

मूल्य, हम साथ समाप्त होते हैं

scala> math.pow (54, 16)
res6: Double = 5.227573613485917E27

चूंकि वहाँ 256 के नीचे 54 primes हैं।


2
5.22e27 >> 2^16। कई संभावनाओं को बल देने का कोई तरीका नहीं है।
कीथ रान्डेल

आप भाषा का नाम भूल गए
ajax333221

@ ajax333221: स्काला। मैंने इसे शीर्ष पर जोड़ा।
उपयोगकर्ता अज्ञात

@KeithRandall: मैं 'गलती से' केवल पॉजिटिव बाइट्स का उपयोग कर सकता था, जो कि गणित की संभावनाओं को कम करेगा। (27, 16), लेकिन यह अभी भी 8e22 के बारे में है।
उपयोगकर्ता अज्ञात
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.