सी (+ सॉकेट), 433 429 280 276 270 259 बाइट्स
#define H"medalbot.com"
char**p,B[999],*b=B;main(f){connect(f=socket(2,1,getaddrinfo("www."H,"80",0,&p)),p[4],16);send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost:"H"\r\n\r\n",69);read(f,b,998);for(f=3;f--;puts(p))b=strchr(p=strstr(++b,"_n")+9,34),*b=0;}
तो यह पता चला है कि सी इंटरनेट से संसाधनों को डाउनलोड करने और उन्हें JSON के रूप में पार्स करने में महान नहीं है। किसे पता था?
यह कोड (स्वाभाविक रूप से) त्रुटि जांच के साथ सुपर लक्स है, इसलिए मुझे लगता है कि अगर medalbot.com दुर्भावनापूर्ण डेटा भेजना चाहता था, तो वे बफर ओवरफ्लो को ट्रिगर करने में सक्षम होंगे, आदि। नवीनतम कोड कॉन्स्टेंट के लिए कुछ मूल्यों की अपेक्षा करता है (जैसे AF_INET = 2
) जो शायद हर जगह मामला होगा , लेकिन इसकी गारंटी नहीं है।
यहां मूल कोड है जो इतना नाजुक नहीं है (लेकिन अभी भी बहुत मजबूत या सुरक्षित नहीं है):
#include<netdb.h>
#define H"medalbot.com"
char*b,*B,d[999];struct addrinfo*p,h;main(f){h.ai_socktype=SOCK_STREAM;getaddrinfo("www."H,"80",&h,&p);f=socket(p->ai_family,p->ai_socktype,p->ai_protocol);connect(f,p->ai_addr,p->ai_addrlen);send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost: "H":80\r\nConnection: close\r\n\r\n",92,0);recv(f,d,998,0);for(f=0,b=d;f<3;++f)B=strstr(b,"_n")+9,b=strchr(B,'}'),*strchr(B,'"')=0,puts(B);}
टूट - फूट:
// No imports needed whatsoever!
#define H"medalbot.com" // Re-use the host in multiple places
char**p, // This is actually a "struct addrinfo*"
B[999], // The download buffer (global to init with 0)
*b=B; // A mutable pointer to the buffer
main(f){
// Hope for the best: try the first suggested address with no fallback:
// (medalbot.com runs on Heroku which has dynamic IPs, so we must look up the
// IP each time using getaddrinfo)
f=socket(2,1,getaddrinfo("www."H,"80",0,&p));
// 2 = AF_INET
// 1 = SOCK_STREAM
// (may not match getaddrinfo, but works anyway)
// 0 = IP protocol (getaddrinfo returns 0 on success)
connect(f,p[4],16); // struct addrinfo contains a "struct sockaddr" pointer
// which is aligned at 32 bytes (4*8)
// Send the HTTP request (not quite standard, but works. 69 bytes long)
send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost:"H"\r\n\r\n",69);
// (omit flags arg in send and hope 0 will be assumed)
read(f,b,998); // Get first 998 bytes of response; same as recv(...,0)
// Loop through the top 3 & print country names:
// (p is re-used as a char* now)
for(f=3;f--;puts(p)) // Loop and print:
p=strstr(++b,"_n")+9, // Find "country_name": "
b=strchr(p,34), // Jump to closing "
*b=0; // Set the closing " to \0
}
यह सर्वर के लिए बहुत अच्छा नहीं है क्योंकि हम Connection: close\r\n
HTTP अनुरोध के हिस्से के रूप में नहीं भेजते हैं। यह Accept
शीर्षलेख को भी छोड़ देता है क्योंकि medalbot.com किसी भी मामले में कम्प्रेशन का उपयोग नहीं करता है, और इसके बाद स्पेस को याद करता है Host:
(फिर से, सर्वर को यह ठीक लगता है)। ऐसा नहीं लगता कि हालांकि कुछ और हटाया जा सकता है।
एक बार ओलंपिक समाप्त होने के बाद, इस कार्यक्रम के लिए सबसे अधिक संभावना व्यवहार मेमोरी स्थान को पढ़ने की कोशिश करना है। जब तक कि एक दुष्ट हैकर डोमेन पर कब्जा न कर ले, उस स्थिति में सबसे संभावित व्यवहार यह है कि पते में कुछ बाइट को 0 पर सेट करना है। जानकारी संरचना, जो वास्तव में बहुत खतरनाक नहीं है। लेकिन इन दुष्ट हैकर्स के साथ कौन बता सकता है?