2012-03-02 13 views
11

इस प्रश्न से संबंधित कोड यहाँ है: https://github.com/jchester/lua-polarssl/tree/master/srcलुआ के लिए एक सी पुस्तकालय लपेटना: मैं कार्यों की नेस्टेड टेबल कैसे बना सकता हूं?

वर्तमान में मैं PolarSSL पुस्तकालय (http://polarssl.org) के एक भाग रैप करने के लिए मुझे SHA-512 HMACs तक पहुंच प्रदान करना कोशिश कर रहा हूँ (luacrypto करता है यह प्रदान नहीं करें)।

एपीआई मैं के लिए लक्ष्य कर रहा हूँ फार्म की है:

a_sha512_hash = polarssl.hash.sha512('text') 

या अधिक पूरी तरह से

local polarssl = require 'polarssl' 
local hash = polarssl.hash 

a_sha512_hash = hash.sha512('test') 

उपरोक्त लिंक पर polarssl.c को देखें, तो आप मुझे देखेंगे पोलरएसएसएल कोड को लपेटने वाले कार्यों को लिखा गया है। तब मैं कार्य तालिकाओं इस प्रकार बनाने की कोशिश कर रहा हूँ:

LUA_API int luaopen_polarssl(lua_State *L) { 
    static const struct luaL_Reg core[] = { 
    { NULL, NULL } 
    }; 

    static const struct luaL_Reg hash_functions[] = { 
    { "sha512", hash_sha512 }, 
    { "sha384", hash_sha384 }, 
    { NULL, NULL } 
    }; 

    static const struct luaL_Reg hmac_functions[] = { 
    { "sha512", hmac_sha512 }, 
    { "sha384", hmac_sha384 }, 
    { NULL, NULL } 
    }; 

    luaL_register(L, CORE_MOD_NAME, core); 
    luaL_register(L, HASH_MOD_NAME, hash_functions); 
    luaL_register(L, HMAC_MOD_NAME, hmac_functions); 

    return 1; 
} 

कहाँ CORE_MOD_NAME = 'polarssl', HASH_MOD_NAME = 'polarssl.hash', HMAC_MOD_NAME = 'polarssl.hmac'।

जब मैं एक परीक्षण स्क्रिप्ट इस सवाल के शीर्ष पर लुआ कोड के लिए इसी तरह चलाने के लिए, मैं इस मिल:

lua: test.lua:23: attempt to index global 'polarssl' (a nil value) 
stack traceback: 
    test.lua:23: in main chunk 
    [C]: ? 

मैं कैसे इस module.submodule दृष्टिकोण को प्राप्त करने के उदाहरण के लिए देख कोशिश की है (उदाहरण के लिए naim बनाम luasockets), लेकिन हर किसी को इसे प्राप्त करने का एक अलग तरीका लगता है। मैं पूरी तरह से खो गया हूँ।

+0

मैं नैम और लुसाकेट्स से लिंक नहीं कर सकता क्योंकि मैंने लिंक पर <10 बिंदु सीमा को मारा है। –

+0

ऐसा लगता है कि कर्म को स्वादिष्ट लॉली की तरह सौंप दिया गया है, इसलिए लिंक के साथ अद्यतन पोस्ट किया गया है। –

उत्तर

14

हर किसी को इसे प्राप्त करने का एक अलग तरीका लगता है।

वह लुआ है; हर कोई इसे अपना रास्ता देता है। यह लुआ की सबसे बड़ी ताकत और सबसे बड़ी कमजोरी है: भाषा तंत्र प्रदान करती है, नीतियों नहीं।

सबसे पहले आपको जो करना है वह luaL_register का उपयोग करना बंद कर देता है। हाँ, मुझे पता है कि यह सुविधाजनक है। लेकिन आप कुछ खास चाहते हैं, और luaL_register आपको इसे प्राप्त करने में मदद नहीं करेगा।

आप जो तालिका चाहते हैं वह एक सारणी बनाना है जिसमें एक या अधिक कार्य शामिल हैं। तो ... ऐसा करो।

एक टेबल बनाएं।

lua_newtable(L); 

यह आसान था। फ़ंक्शन स्टैक पर एक टेबल दबाता है, इसलिए हमारे ढेर में अब इसके ऊपर एक टेबल है। यह वह टेबल है जिसे हम वापस कर देंगे।

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

lua_newtable(L); 

फिर से, आसान। इसके बाद, हम उस फ़ंक्शन को रखना चाहते हैं जिसे हम उस तालिका में ढेर पर जाना चाहते हैं। (एक दूसरे में यह "नामकरण" करने के लिए हम मिल जाएगा) गंतव्य तालिका, "हैश" तालिका, और समारोह हम "हैश" में डाल करना चाहते हैं:

lua_pushcfunction(L, hash_sha512); 

तो ढेर तीन बातें है तालिका।

तो फ़ंक्शन को हैश तालिका में रखें।

lua_setfield(L, -2, "sha512"); 

यह लेता है जो कुछ भी ढेर के शीर्ष पर है और क्षेत्र स्टैक पर -2 सूचकांक में मेज पर "SHA512" नाम में यह तय करता है। यही वह जगह है जहां हमारी "हैश" तालिका है। इस समारोह को पूरा करने के बाद, यह स्टैक से शीर्ष आइटम को हटा देता है। यह शीर्ष पर "हैश" तालिका छोड़ देता है।

हम दूसरे समारोह के लिए प्रक्रिया को दोहराने कर सकते हैं:

lua_pushcfunction(L, hash_sha384); 
lua_setfield(L, -2, "sha384"); 

अब, हम तालिका हम वापस करना चाहते में "हैश" तालिका रखना चाहते हैं। यह एक और lua_setfield कॉल के साथ आसानी से पर्याप्त किया है:

lua_setfield(L, -2, "hash"); 

ध्यान दें: यह समारोह जो कुछ ढेर के शीर्ष पर है लेता है। इस बिंदु पर, जिस तालिका को हम वापस करना चाहते हैं (जो हमारी मॉड्यूल की तालिका होगी) ढेर पर है।

हम "HMAC" तालिका के लिए इस प्रक्रिया को दोहराने कर सकते हैं: "हैश" और "HMAC":

lua_newtable(L); //Create "hmac" table 
lua_pushcfunction(L, hmac_sha512); 
lua_setfield(L, -2, "sha512"); 
lua_pushcfunction(L, hmac_sha384); 
lua_setfield(L, -2, "sha384"); 
lua_setfield(L, -2, "hmac"); //Put the "hmac" table into our module table 

मॉड्यूल की मेज अब इसमें दो प्रविष्टियां हैं। दोनों टेबल में दो कार्यों के साथ टेबल हैं।

हम इस के साथ वैश्विक तालिका में यह छड़ी कर सकते हैं:

lua_pushvalue(L, -1); 
lua_setfield(L, LUA_GLOBALSINDEX, "polarssl"); 

हर मॉड्यूल निर्माता है कि करना चाहती है। कुछ लोग वैश्विक नामस्थान प्रदूषण से बचने के लिए local polarssl = require "polarssl" वाक्यविन्यास का उपयोग करने के लिए मजबूर करना पसंद करते हैं। यह आप पर निर्भर करता है।

लेकिन आपको यह भी करना चाहिए कि इस तालिका को पर वापस करें। लुआ को यह जानने के लिए कि आपके पास एक वापसी मूल्य है, luaopen फ़ंक्शन से 1 लौटें। lua_pushvalue उपरोक्त कॉल तालिका की प्रतिलिपि बनाने के एकमात्र उद्देश्य के लिए मौजूद है (याद रखें: तालिकाओं का संदर्भ दिया जाता है, इसलिए यह एक सूचक की प्रतिलिपि बनाने जैसा है)। इस तरह, जब आप lua_setfield का उपयोग करते हैं, तो प्रतिलिपि स्टैक से हटा दी जाती है, जबकि मूल अवशेष रिटर्न मान के रूप में उपयोग किया जाता है।

+0

धन्यवाद। मैं पहले थोड़ा परेशान था, लेकिन कागज पर ढेर आंदोलनों को स्केच करने से मुझे प्रक्रिया पर पकड़ने में मदद मिली। –

+3

+1 'आवश्यकता' से वापसी मूल्य पर चर्चा करने के लिए कुछ परेशानी के लिए +1 ... बहुत से लोगों को वास्तव में पता नहीं है कि अनुशंसित अभ्यास "बस अपने मॉड्यूल को वैश्विक में चिपकाएं" से वापस लौटा दिया गया है आपके मॉड्यूल की आवश्यकता से, और कॉलर को स्थानीय चर में रखना चाहिए " – snogglethorpe

2

नहीं सीधे प्रश्न से संबंधित है, लेकिन निम्न कथन पूरी तरह सच नहीं है:

वर्तमान में मैं PolarSSL पुस्तकालय का एक हिस्सा रैप करने के लिए कोशिश कर रहा हूँ (http://polarssl.org) देने के लिए मुझे एसएचए -512 एचएमएसी तक पहुंच (लुकाप्रिपो यह प्रदान नहीं करता है)।

मैं नहीं जानता कि LuaCrypto का कौन सा संस्करण की बात कर रहे हैं, लेकिन this LuaCrypto fork SHA-512 HMACs प्रदान करता है, और किसी भी अन्य स्वचालित रूप से OpenSSL द्वारा समर्थित प्रकार पचाने। बस प्रकार पचाने के रूप में "sha512" पारित:

hmac.digest("sha512", message, key) 

प्रलेखन समर्थित डाइजेस्ट प्रकार का केवल एक हिस्सा कहा गया है, पूरी सूची crypto.list("digests") फोन करके प्राप्त किया जा सकता है।

table.foreach(crypto.list("digests"), print) 

जब मैं इसके बारे में सोचता हूं, यहां तक ​​कि मूल लुआक्रिप्टो को SHA-512 का समर्थन करना चाहिए।

+0

धन्यवाद, मुझे इसके बारे में पता नहीं था। हालांकि, मैं "मुख्य" कांटा चला रहा था जो SHA512 को लपेटता नहीं है। मैंने पोलारएसएसएल को लपेटना चुना क्योंकि यह छोटा है और एपीआई बहुत आसान है - प्रत्येक मॉड्यूल स्टैंडअलोन है और इसे स्वतंत्र रूप से संकलित किया जा सकता है। उदाहरण के लिए, मैंने केवल SHA512/384 मॉड्यूल संकलित किया है। कुल आकार: 22 किलो। –

+0

यह वास्तव में एक बहुत ही उचित आकार है! अगर आप लुआ को क्रिप्टोग्राफिक क्षमताओं के साथ एम्बेड करना चाहते हैं तो बहुत अच्छा लगता है। –

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

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