| SN0INT(1) | sn0int | SN0INT(1) |
نام (NAME)
sn0int - چارچوب و مدیر بسته نیمهخودکار OSINT
در دست تکمیل
اجرای نخستین کاوش (RUNNING YOUR FIRST INVESTIGATION)
این صفحه شما را در مراحل راهاندازی محیط و اجرای نخستین کاوش خود راهنمایی میکند.
نصب ماژولهای پیشفرض
بهصورت پیشفرض، هیچ ماژولی روی sn0int نصب نیست. اگر sn0int را اجرا کنید، تعدادی از فایلهای مورد نیازش را بارگیری کرده و سپس نصب مجموعهای از ماژولهای توصیهشده را پیشنهاد میدهد:
$ sn0int
___/ .
____ , __ .' /\ ` , __ _/_
( |' `. | / | | |' `. |
`--. | | |,' | | | | |
\___.' / | /`---' / / | \__/
osint | recon | security
irc.hackint.org:6697/#sn0int
[+] Connecting to database
[+] Downloading public suffix list
[+] Downloading "GeoLite2-City.mmdb"
[+] Downloading "GeoLite2-ASN.mmdb"
[+] Loaded 0 modules
[*] No modules found, run pkg quickstart to install default modules
[sn0int][default] >
با وارد کردن pkg quickstart تعداد قابلتوجهی از ماژولهای برگزیده نصب خواهند شد:
[sn0int][default] > pkg quickstart [+] Installing kpcyrd/asn [+] Installing kpcyrd/ctlogs [+] Installing kpcyrd/dns-resolve [+] Installing kpcyrd/geoip [+] Installing kpcyrd/hackertarget-subdomains [+] Installing kpcyrd/otx-subdomains [+] Installing kpcyrd/passive-spider [+] Installing kpcyrd/pgp-keyserver [+] Installing kpcyrd/threatminer-ipaddr [+] Installing kpcyrd/threatminer-subdomains [+] Installing kpcyrd/url-scan [+] Installing kpcyrd/waybackurls [+] Loaded 12 modules [sn0int][default] >
احتمالاً میخواهید بررسیهای خود را تفکیک کنید، بنابراین باید یک فضای کاری (workspace) انتخاب کنید تا نتایج شما در آن ذخیره شوند:
[sn0int][default] > workspace demo [+] Connecting to database [sn0int][demo] >
در مرحله بعد، باید کار را از جایی آغاز کنیم و نخستین موجودیت (entity) را به محدوده کاری (scope) خود بیفزاییم:
[sn0int][demo] > add domain Domain: example.com [sn0int][demo] >
نکته:
توجه داشته باشید که example.com میتواند به عنوان یک زیردامنه نیز افزوده شود چرا که میتواند دربردارنده رکوردها باشد. در این حالت، example.com هم نام منطقه dns (dns zone) است و هم یک موجودیت درون آن منطقه.
میتوانید با اجرای یک دستور select بر روی دامنههایی که اکنون داریم، این مورد را تأیید کنید:
[sn0int][demo] > select domains #1, "example.com" [sn0int][demo] >
چیزی که در حال حاضر به آن نیازی نداریم، اما بعداً بسیار کاربردی خواهد بود، قابلیت فیلتر کردن موجودیتهایتان است:
[sn0int][demo] > select domains where id=1 #1, "example.com" [sn0int][demo] > [sn0int][demo] > select domains where value like %.com #1, "example.com" [sn0int][demo] > [sn0int][demo] > select domains where ( value like e% and value like %m ) or false #1, "example.com" [sn0int][demo] >
نکته:
اجرای یک ماژول (Running a module)
اکنون که دادهای برای شروع داریم، میتوانیم نخستین ماژول خود را اجرا کنیم. ابتدا بیایید تمام ماژولهایی را که در اختیار داریم فهرست کنیم:
[sn0int][demo] > pkg list
kpcyrd/asn (0.1.0)
Run a asn lookup for an ip address
kpcyrd/ctlogs (0.1.0)
Query certificate transparency logs to discover subdomains
kpcyrd/dns-resolve (0.1.0)
Query subdomains to discovery ip addresses and verify the record is visible
kpcyrd/geoip (0.1.0)
Run a geoip lookup for an ip address
kpcyrd/hackertarget-subdomains (0.1.0)
Query hackertarget for subdomains of a domain
kpcyrd/otx-subdomains (0.1.0)
Query alienvault otx passive dns for subdomains of a domain
kpcyrd/passive-spider (0.1.0)
Scrape known http responses for urls
kpcyrd/pgp-keyserver (0.1.0)
Query pgp keyserver for email addresses
kpcyrd/threatminer-ipaddr (0.1.0)
Query ThreatMiner passive dns for subdomains of an ip address
kpcyrd/threatminer-subdomains (0.1.0)
Query ThreatMiner passive dns for subdomains of a domain
kpcyrd/url-scan (0.1.0)
Scan subdomains for websites
kpcyrd/waybackurls (0.1.0)
Discover subdomains from wayback machine
[sn0int][demo] >
بیایید با پرسوجو از گزارشهای شفافیت گواهی (certificate transparency logs) آغاز کنیم:
[sn0int][demo] > use ctlogs [sn0int][demo][kpcyrd/ctlogs] > run [*] "example.com" : Subdomain: "www.example.com" [*] "example.com" : Subdomain: "m.example.com" [*] "example.com" : Subdomain: "dev.example.com" [*] "example.com" : Subdomain: "products.example.com" [*] "example.com" : Subdomain: "support.example.com" [+] Finished kpcyrd/ctlogs [sn0int][demo][kpcyrd/ctlogs] >
به نظر میرسد در اینجا چند زیردامنه کشف کردهایم. شاید وسوسهانگیز باشد که برخی از آنها را فوراً در مرورگر باز کنید، اما دست نگه دارید؛ روش بسیار کارآمدتری برای انجام این کار وجود دارد.
راهنمایی:
زمان زیادی صرف بخش پایگاهداده شده است. با اینکه تا حدی شبیه به یک پایگاهدادهٔ no-sql به نظر میرسد، ما در واقع با دلیل موجهی به جای استفاده از دیکشنریهای عمومی و رها کردن کار، یک ساختار مشخص (schema) را اِعمال میکنیم.
بسیار حیاتی است که موجودیتهای ایجادشده توسط یک ماژول، همانند قطعات لگو، توسط ماژول دیگری قابل دریافت و استفاده باشند. بیایید با ماژولی برای پرسوجوی رکوردهای dns کار را ادامه دهیم:
[sn0int][demo][kpcyrd/ctlogs] > use dns-resolve [sn0int][demo][kpcyrd/dns-resolve] > run [*] "www.example.com" : Updating "www.example.com" (resolvable => true) [*] "www.example.com" : IpAddr: 93.184.216.34 [*] "www.example.com" : "www.example.com" -> 93.184.216.34 [*] "m.example.com" : Updating "m.example.com" (resolvable => false) [*] "dev.example.com" : Updating "dev.example.com" (resolvable => false) [*] "products.example.com" : Updating "products.example.com" (resolvable => false) [*] "support.example.com" : Updating "support.example.com" (resolvable => false) [+] Finished kpcyrd/dns-resolve [sn0int][demo][kpcyrd/dns-resolve] >
در اینجا دو اتفاق رخ داد: تعدادی آدرس IP شناسایی کردیم و آنها را به محدوده (scope) افزودیم، و همچنین موجودیتهای زیردامنهٔ خود را با اطلاعات جدید بهروزرسانی کردیم، زیرا اکنون میدانیم کدامیک از آنها قابل تحلیل (resolvable) هستند و کدامیک نیستند.
بیایید ماژول بعدی را اجرا کنیم که وجود وبسایتها روی آنها را بررسی میکند؛ اما تنها زیردامنههایی را هدف قرار میدهیم که میدانیم قابل تحلیل (resolvable) هستند:
[sn0int][demo][kpcyrd/dns-resolve] > use url-scan
[sn0int][demo][kpcyrd/url-scan] > target
#1, "www.example.com"
93.184.216.34
#2, "m.example.com"
#3, "dev.example.com"
#4, "products.example.com"
#5, "support.example.com"
[sn0int][demo][kpcyrd/url-scan] > target where resolvable
[+] 1 entities selected
[sn0int][demo][kpcyrd/url-scan] > target
#1, "www.example.com"
93.184.216.34
[sn0int][demo][kpcyrd/url-scan] >
میتوانیم با دستور target اهدافی را که قرار است به ماژول فرستاده شوند، هم پیشنمایش دهیم و هم محدود کنیم. پس از اینکه از انتخاب خود مطمئن شدیم، میتوانیم این ماژول را اجرا کنیم:
[sn0int][demo][kpcyrd/url-scan] > run [*] "www.example.com" : Url: "http://www.example.com/" (200) [*] "www.example.com" : Url: "https://www.example.com/" (200) [+] Finished kpcyrd/url-scan [sn0int][demo][kpcyrd/url-scan] >
ما اکنون هر دو پورت 80 و 443 را برای هر زیردامنه کاوش (probe) کرده و از این طریق دو پاسخ http دریافت کردهایم. اگر فهرستی از نشانیها (urls) را میخواهید که ممکن است مایل باشید در مرورگر خود بررسی کنید، اکنون میتوانید از آنها پرسوجو بگیرید:
[sn0int][demo][kpcyrd/url-scan] > select urls #1, "http://www.example.com/" (200) #2, "https://www.example.com/" (200) [sn0int][demo][kpcyrd/url-scan] >
یکی از مواردی که با آن روبرو خواهید شد این است که ماژولها ممکن است بیش از حد حریصانه عمل کرده و مواردی را به دامنه بیفزایند که مورد نظر ما نیستند. شما میتوانید آنها را با استفاده از دستور delete حذف کنید، اما احتمالاً مجدداً توسط یک ماژول جمعآوری خواهند شد.
کاری که میتوانید به جای آن انجام دهید، تنظیم یک پرچم (flag) روی یک موجودیت است که آن را از دامنه خارج میکند. این کار با استفاده از دستور noscope انجام میشود:
[sn0int][demo] > use ctlogs [sn0int][demo][kpcyrd/ctlogs] > target #1, "example.com" [sn0int][demo][kpcyrd/ctlogs] > add domain Domain: google.com [sn0int][demo][kpcyrd/ctlogs] > target #1, "example.com" #2, "google.com" [sn0int][demo][kpcyrd/ctlogs] > noscope domains where value=google.com [+] Updated 1 rows [sn0int][demo][kpcyrd/ctlogs] > target #1, "example.com" [sn0int][demo][kpcyrd/ctlogs] >
موجودیتهایی که از دامنه خارج شدهاند (unscoped)، به طور خودکار توسط تمام ماژولها نادیده گرفته میشوند.
میتوانید با استفاده از دستور scope این عمل را بازگردانی کنید:
[sn0int][demo][kpcyrd/ctlogs] > target #1, "example.com" [sn0int][demo][kpcyrd/ctlogs] > scope domains where true [+] Updated 2 rows [sn0int][demo][kpcyrd/ctlogs] > target #1, "example.com" #2, "google.com" [sn0int][demo][kpcyrd/ctlogs] >
نکته:
پیکربندی (CONFIGURATION)
این بخش مستندات فایل پیکربندی را شرح میدهد. به طور پیشفرض این فایل وجود ندارد و به جای آن از یک پیکربندی پیشفرض استفاده میشود.
[core]
- registry
- رجیستری مورد نظری را که میخواهید استفاده کنید پیکربندی میکند. مقدار پیشفرض https://sn0int.com است.
- no-autoupdate
- ابزار sn0int
هنگام
راهاندازی،
هفتهای یک
بار بررسی
میکند که
آیا
ماژولهای
شما قدیمی
شدهاند یا
خیر. این
گزینه را
روی true
تنظیم کنید
تا این
قابلیت
غیرفعال
شود.
بهطور پیشفرض فرض میشود که ماژولهای sn0int از رجیستری نصب شدهاند. ممکن است بخواهید بهویژه در هنگام توسعه، یک دایرکتوری محلی با ماژولهای خصوصی نگه دارید. میتوانید با افزودن یک بخش namespace به فایل پیکربندی، پوشهای شامل ماژولهایی که توسط sn0int مدیریت نمیشوند را پیکربندی کنید:
[namespaces] foo = "/opt/sn0int/foo" bar = "~/repos/a/b/c/sn0int-modules"
این کار ماژولها را از این دو پوشه بارگذاری کرده و آنها را در فضای نام foo و bar ثبت میکند.
توجه داشته باشید که sn0int همچنین فرض میکند پیوندهای نمادین در ~/.local/share/sn0int/modules و پوشههای حاوی یک پوشهٔ .git بهصورت خارجی مدیریت میشوند.
[network]
برای فعالسازی یک پراکسی، موارد زیر را به فایل پیکربندی خود اضافه کنید:
[network] proxy = "127.0.0.1:9050"
این کار همه چیز را از طریق tor (یا هر پراکسی socks5 دیگر) هدایت کرده و تمام توابع دیگر وابسته به شبکه را محدود میکند. برای نمونه، در صورت پیکربندی یک پراکسی، تابع dns بهطور کامل غیرفعال میشود.
مرجع توابع (FUNCTION REFERENCE)
asn_lookup
یک جستجوی ASN را برای نشانی IP دادهشده اجرا میکند. این تابع asn و as_org را بازمیگرداند. این تابع ممکن است با شکست مواجه شود.
lookup = asn_lookup('1.1.1.1')
if last_err() then return end
base64_decode
یک رشتهٔ base64 را با الفبا و پدینگ (padding) پیشفرض رمزگشایی میکند.
base64_decode("ww==")
base64_encode
یک آرایهٔ باینری را با base64 و الفبا و پدینگ (padding) پیشفرض کدگذاری میکند.
base64_encode("\x00\xff")
base64_custom_decode
یک رشتهٔ base64 را با الفبا و پدینگ (padding) سفارشی رمزگشایی میکند.
-- base64
base64_custom_decode('b2hhaQ==', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', '=')
-- base64 no padding
base64_custom_decode('b2hhaQ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', '')
-- base64 url safe
base64_custom_decode('b2hhaQ==', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', '=')
کدگذاری یک آرایه باینری با base64 و الفبا+پدینگ سفارشی.
-- base64
base64_custom_encode('ohai', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', '=')
-- base64 no padding
base64_custom_encode('ohai', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', '')
-- base64 url safe
base64_custom_encode('ohai', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', '=')
base32_custom_decode
رمزگشایی یک رشته base32 با الفبا+پدینگ سفارشی.
-- rfc-4648 base32
base32_custom_decode('N5UGC2I=', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', '=')
-- z-base-32
base32_custom_decode('p7wgn4e', 'ybndrfg8ejkmcpqxot1uwisza345h769', '')
base32_custom_encode
کدگذاری یک آرایه باینری با base32 و الفبا+پدینگ سفارشی.
-- rfc-4648 base32
x = base32_custom_encode('ohai', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', '=')
-- z-base-32
x = base32_custom_encode('ohai', 'ybndrfg8ejkmcpqxot1uwisza345h769', '')
clear_err
پاک کردن آخرین خطای ثبتشده از وضعیت داخلی. همچنین ببینید: last_err.
if last_err() then
-- ignore this error
clear_err()
end
create_blob
قرار دادن یک آرایه بایتی در فضای ذخیرهسازی پایای blob. این کار اجازه میدهد تا این بایتها به توابعی که روی ذخیرهساز blob عمل میکنند منتقل شوند. یک شناسه blob بازمیگرداند که بر اساس محتوای blob قطعی است. دادههای blob تغییرناپذیر هستند.
blob = create_blob("some bytes")
debug(blob)
datetime
بازگرداندن زمان فعلی در UTC. این تابع برای تعیین تاریخ و زمان برای فیلدهای پایگاهداده DATETIME مناسب است.
now = datetime()
نکته:
هشدار:
یک موجودیت را به پایگاهداده اضافه میکند یا در صورت وجود، آن را بهروزرسانی میکند. این تابع ممکن است با شکست مواجه شود یا nil بازگرداند. برای جزئیات، db_add را ببینید.
domain_id = db_add('domain', {
value='example.com',
})
db_add_ttl
یک موجودیت موقت را به پایگاهداده اضافه میکند. این تابع معمولاً برای درج پیوندهای موقتی استفاده میشود که با گذشت زمان بهطور خودکار منقضی میشوند. اگر موجودیت از قبل وجود داشته باشد و همچنین به عنوان موقت علامتگذاری شده باشد، ttl جدید جایگزین ttl قبلی خواهد شد. اگر موجودیت از قبل وجود داشته باشد اما هرگز منقضی نشود، ttl جدیدی اضافه نخواهد شد.
-- this link is valid for 2min
domain_id = db_add_ttl('network-device', {
network_id=1,
device_id=13,
}, 120)
db_activity
یک رویداد فعالیت را ثبت میکند. یک رویداد پایه به این شکل است:
db_activity({
topic='harness/activity-ping:dummy',
time=sn0int_time(),
content={
a='b',
foo={
bar=1337,
},
msg='ohai',
},
})
این تابع با جزئیات در بخش activity توضیح داده شده است.
db_select
بررسی میکند که آیا یک هدف در محدوده (scope) قرار دارد یا خیر. اگر مقداری غیر از nil بازگردانده شود، این موجودیت در محدوده قرار دارد. این تابع ممکن است با شکست مواجه شود. برای جزئیات، db_select را ببینید.
domain_id = db_select('domain', 'example.com')
if domain_id ~= nil then
-- do something
end
db_update
یک موجودیت را در پایگاهداده بهروزرسانی میکند. این تابع ممکن است با شکست مواجه شود. برای جزئیات، db_update را ببینید.
db_update('ipaddr', arg, {
asn=lookup['asn'],
as_org=lookup['as_org'],
})
یک رکورد dns را تحلیل میکند. اگر پرسوجوی dns موفقیتآمیز باشد و پاسخ dns برابر با NoError باشد، مقدار x['error'] برابر با nil خواهد بود. رکوردهای پاسخ در x['answers'] قرار دارند. این تابع ممکن است با شکست مواجه شود.
این تابع گزینههای زیر را میپذیرد:
- record
- مقدار query_type؛ میتواند هر یک از A، AAAA، MX، AXFR و غیره باشد.
- nameserver
- سروری که باید برای جستجو استفاده شود. پیشفرض، تحلیلگر سیستم شما است.
- tcp
- مشخص میکند که آیا جستجو باید از tcp استفاده کند یا خیر، true/false.
- timeout
- مدت زمان تا اتمام مهلت پرسوجو به میلیثانیه.
records = dns('example.com', {
record='A',
})
if last_err() then return end
if records['error'] ~= nil then return end
records = records['answers']
نکته:
نکته:
error
یک خطا را در ترمینال ثبت میکند.
error('ohai')
geoip_lookup
یک جستجوی geoip را برای یک نشانی ip مشخص اجرا میکند. این تابع موارد زیر را برمیگرداند:
- continent
- continent_code
- country
- country_code
- city
- latitude
- longitude
این تابع ممکن است با شکست مواجه شود.
lookup = geoip_lookup('1.1.1.1')
if last_err() then return end
کدگذاری هگز (Hex) فهرستی از بایتها.
hex("\x6F\x68\x61\x69\x0A\x00")
hmac_md5
محاسبه یک hmac با md5. یک آرایه باینری را بازمیگرداند.
hmac_md5("secret", "my authenticated message")
hmac_sha1
محاسبه یک hmac با sha1. یک آرایه باینری را بازمیگرداند.
hmac_sha1("secret", "my authenticated message")
hmac_sha2_256
محاسبه یک hmac با sha2_256. یک آرایه باینری را بازمیگرداند.
hmac_sha2_256("secret", "my authenticated message")
hmac_sha2_512
محاسبه یک hmac با sha2_512. یک آرایه باینری را بازمیگرداند.
hmac_sha2_512("secret", "my authenticated message")
hmac_sha3_256
محاسبه یک hmac با sha3_256. یک آرایه باینری را بازمیگرداند.
hmac_sha3_256("secret", "my authenticated message")
hmac_sha3_512
محاسبه یک hmac با sha3_512. یک آرایه باینری را بازمیگرداند.
hmac_sha3_512("secret", "my authenticated message")
html_select
یک سند html را تجزیه کرده و نخستین عنصری را که با انتخابگر css مطابقت دارد بازمیگرداند. مقدار بازگشتی یک جدول است که در آن text متن درونی و attrs جدولی از ویژگیهای عنصر است.
csrf = html_select(html, 'input[name="csrf"]') token = csrf["attrs"]["value"]
همانند html_select است اما به جای مورد اول، تمام موارد منطبق را بازمیگرداند.
html_select_list(html, 'input[name="csrf"]')
http_mksession
یک شیء نشست (session) ایجاد میکند. این تابع شبیه به requests.Session در python-requests است و وضعیت کوکیها را دنبال و نگهداری میکند.
session = http_mksession()
http_request
یک درخواست http آماده میکند. آرگومان نخست، ارجاع به نشست است و کوکیهای مربوط به آن نشست درون درخواست کپی میشوند. پس از ارسال درخواست، کوکیهای حاصل از پاسخ دوباره به درون نشست کپی میشوند.
آرگومانهای بعدی عبارتند از method، url و گزینههای اضافی. لطفاً توجه داشته باشید که حتی اگر هیچ گزینهای تنظیم نشده باشد، باز هم باید یک جدول خالی {} مشخص کنید. گزینههای زیر در دسترس هستند:
- query
- نگاشتی از پارامترهای query که باید روی url تنظیم شوند.
- headers
- نگاشتی از سرایندها (headers) که باید تنظیم شوند.
- basic_auth
- پیکربندی سرایند basic auth با {"user, "password"}.
- user_agent
- بازنویسی user agent پیشفرض با یک رشته.
- json
- بدنه درخواست که باید بهصورت json کدگذاری شود.
- form
- بدنه درخواست که باید بهصورت form کدگذاری شود.
- follow_redirects
- دنبال کردن خودکار تغییرمسیرها (redirects) تا تعداد مشخصشده. اگر روی 1 تنظیم شود، تنها یک تغییرمسیر دنبال خواهد شد. مقدار پیشفرض 0 است، بنابراین تغییرمسیرها دنبال نمیشوند.
- body
- بدنه خام درخواست بهصورت رشته.
- into_blob
- اگر true باشد، بدنه پاسخ در فضای ذخیرهسازی blob ذخیره میشود و به جای بدنه کامل، یک ارجاع به blob بهعنوان blob بازگردانده میشود.
- proxy
- استفاده از یک پراکسی socks5 در قالب 127.0.0.1:9050. این گزینه تنها در صورتی کار میکند که با تنظیمات سراسری پراکسی تداخل نداشته باشد.
- binary
- روی true تنظیم شود تا پاسخ http بهصورت بایتهای خام دریافت گردد.
این تابع ممکن است با شکست مواجه شود.
req = http_request(session, 'POST', 'https://httpbin.org/post', {
json={
user=user,
password=password,
}
})
resp = http_send(req)
if last_err() then return end
if resp['status'] ~= 200 then return 'http status error: ' .. resp['status'] end
درخواستی که با http_request ساخته شده است را ارسال میکند. یک جدول با کلیدهای زیر برمیگرداند:
req = http_request(session, 'POST', 'https://httpbin.org/post', {
json={
user=user,
password=password,
}
})
resp = http_send(req)
if last_err() then return end
if resp['status'] ~= 200 then return 'http status error: ' .. resp['status'] end
http_fetch
این تابع یک http_send انجام داده و همچنین کد وضعیت را بهطور خودکار اعتبارسنجی میکند.
نکته:
-- short form data = http_fetch(req) if last_err() then return end -- long form resp = http_send(req) if last_err() then return end if resp['status'] ~= 200 then return 'http status error: ' .. resp['status'] end
http_fetch_json
همانند http_fetch است، اما بدنه پاسخ را نیز بهطور خودکار بهصورت json تجزیه میکند.
-- short form data = http_fetch_json(req) if last_err() then return end -- long form resp = http_send(req) if last_err() then return end if resp['status'] ~= 200 then return 'http status error: ' .. resp['status'] end data = json_decode(resp['text']) if last_err() then return end
تلاش برای رمزگشایی یک blob به عنوان تصویر و بازگرداندن فرادادههای اولیهای مانند mime type، ارتفاع و عرض.
img = img_load(blob) if last_err() then return end debug(img)
img_exif
استخراج فرادادههای exif از یک تصویر.
exif = img_exif(blob) if last_err() then return end debug(exif)
img_ahash
محاسبه هش ادراکی Mean (aHash).
hash = img_ahash(blob) if last_err() then return end debug(hash)
img_dhash
محاسبه هش ادراکی Gradient (dHash).
hash = img_dhash(blob) if last_err() then return end debug(hash)
img_phash
محاسبه هش ادراکی DCT (pHash).
hash = img_phash(blob) if last_err() then return end debug(hash)
img_nudity
طبقهبندی یک تصویر از نظر برهنگی. امتیاز از 0 تا 2 متغیر است. امتیاز بالاتر از 1 به این معنی است که برهنگی تشخیص داده شده است.
nudity = img_nudity(blob) if last_err() then return end debug(nudity)
ثبت یک پیام اطلاعاتی (info) در ترمینال.
info('ohai')
intval
تجزیه یک عدد از یک رشته.
json_decode
رمزگشایی یک مقدار lua از یک رشته json.
json_decode("{\"data\":{\"password\":\"fizz\",\"user\":\"bar\"},\"list\":[1,3,3,7]}")
json_decode_stream
بسیار شبیه به json_decode است، اما با چندین شیء json که مستقیماً به یکدیگر متصل شدهاند یا با خطوط جدید جدا شدهاند کار میکند.
json_decode_stream("{\"data\":1}{\"data\":2}")
json_encode
کدگذاری یک ساختار داده به صورت یک رشته.
x = json_encode({
some=1,
fancy={
data='structures',
}
})
print(x)
key_trunc_pad
کوتاهسازی یا پر کردن (truncate/pad) یک کلید تا یک طول مشخص.
-- if longer than 32 bytes: truncate to 32 -- if shorter than 32 bytes: pad with \x00 local key = key_trunc_pad(password, 32, 0)
keyring
درخواست تمام کلیدها از یک فضاینام (namespace) مشخص. برای جزئیات به بخش keyring مراجعه کنید.
creds = keyring('aws')
print(creds[1]['accesskey'])
print(creds[1]['secretkey'])
اطلاعاتی را درباره آخرین خطای مشاهدهشده (در صورت وجود) برمیگرداند. در غیر این صورت nil را بازمیگرداند.
if last_err() then
-- Something went wrong, abort
return
end
md5
یک آرایه بایتی را با md5 هش کرده و نتیجه را بهصورت بایت بازمیگرداند.
hex(md5("\x00\xff"))
mqtt_connect
به یک کارگزار mqtt متصل میشود.
local sock = mqtt_connect('mqtts://mqtt.example.com', {
username='foo',
password='secret',
})
if last_err() then return end
mqtt_subscribe
در یک موضوع (topic) مشترک میشود. در حال حاضر فقط از QoS 0 پشتیبانی میشود.
mqtt_subscribe(sock, '#', 0) if last_err() then return end
mqtt_recv
یک بسته mqtt دریافت میکند. این بسته لزوماً یک بسته publish نیست و ممکن است در آینده بستههای بیشتری اضافه شوند، بنابراین باید نوع آن را بهطور مشخص بررسی کنید.
اگر یک مهلت زمانی خواندن (read timeout) با mqtt_connect تنظیم شده باشد، این تابع در صورت پایان مهلت زمانی خواندن nil بازمیگرداند.
local pkt = mqtt_recv(sock)
if last_err() then return end
if pkt == nil then
-- read timeout, consider sending a ping or disconnect if the previous ping failed
elseif pkt['type'] == 'pong' then
-- broker sent a pong
elseif pkt['type'] == 'publish' then
local payload = utf8_decode(pkt['body'])
if last_err() then return end
info(payload)
end
mqtt_ping
یک بسته pingreq ارسال میکند که باعث میشود کارگزار یک pingresp بفرستد. این تابع برای اطمینان از برقراری و عملکرد صحیح اتصال استفاده میشود.
mqtt_ping(sock) if last_err() then return end
همانند pgp_pubkey_armored، اما بدون مرحلهی unarmor.
pgp_pubkey_armored
استخراج uids، sigs و fingerprint از یک کلید عمومی pgp منطبق با rfc 4880. این تابع ممکن است ناموفق باشد.
key = pgp_pubkey_armored([===[ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2 mQENBFu6q90BCADgD7Q9aH5683yt7hzPktDkAUNAZJHwYhUNeyGK43frPyDRWQmq N+oXTfiYWLQN+d7KNBTnF9uwyBdaLM7SH44lLNYo8W09mVM2eK+wt19uf5HYNgAE 8la45QLo/ce9CQVe1a4oXNWq6l0FOY7M+wLe+G2wMwz8RXGgwd/qQp4/PB5YpUhx nAnzClxvwymrL6BQXsRcKSMSD5bIzIv95n105CvW5Hql7JR9zgOR+gHqVOH8HBUc ZxMumrTM6aKLgAhgM8Sn36gCFOfjlG1b1OFLZhUtgro/nnEOmAurRsCZy8M5h8QM FpZChIH8kgHs90F/CCvGjMq3qvWcH8ZsPUizABEBAAG0NUhhbnMgQWNrZXIgKGV4 YW1wbGUgY29tbWVudCkgPGhhbnMuYWNrZXJAZXhhbXBsZS5jb20+iQFOBBMBCAA4 FiEEyzeO1eEwbB03hcqBM00IodGdlj8FAlu6q90CGwMFCwkIBwIGFQgJCgsCBBYC AwECHgECF4AACgkQM00IodGdlj/AJQgAjmk+iP5b7Jt7+f+lU4Oprlf3f3DG/uh5 Ge6MjV7cvtxlhZJRD5hxGt9RwwnEp61TBSbrem288pM89ilQfTNe0wUr9OzwWzh/ 8Ngl5iWnD2ah3Mpi5R1V/YMNf2cnwVjqNvfkRHdNc43pZOkC2GoiTUn0QY0UBpOW ZMN3//ANi6ZtiK/L0IZQND/gKvOzu/4tfaJeBl26T3cVYj53p3G3jhlb92vVa8SR uL3S3bzd1h5snDgU1uXHmNHGbhkEc4KUneQ0V9/bdZrg6OzFAfM1ghgfoId+YpQH er9L26ISL3QF58wdEXfIdHYEmMlANjBMO2cUlQXgONuCgkMuY7GBmrkBDQRbuqvd AQgA41jqCumCxYV0NdSYNnTSSDRyd69dOUYCAPT80iZ739s7KKJS9X9KVfGmDjfi u2RcfR/KYj53HoyOm4Pm/+ONN8De4ktzXpIpJxGC+O8NBvd9vkboAS6qnCjK7KVE r91ymxxVKp2dzZvVfpIjWVZR5i2EAvS5vw8UK4gL8ALH+S9leJFZrQWcgyoJOJzH Rzr9pesX2HvdgcNG1O6QUArlsnsTnqpi/hu7tQa8tifBpWDeArOA23Y2DgeehdDF lSU/8KD4J+AkFrWWlcTaMsvSChXQkCHEMRIcSOfXtdpX5KJSE7UBQdD1opm+mR79 VeHnuJAAVZZtUZmJA7pjdKykYQARAQABiQE2BBgBCAAgFiEEyzeO1eEwbB03hcqB M00IodGdlj8FAlu6q90CGwwACgkQM00IodGdlj8bMAf+Lq3Qive4vcrCTT4IgvVj arOACdcbtt5RhVBTimT19rDWNH+m+PfPjo3FSlBj5cm70KAXUS2LBFFxhakTZ/Mq cQroWZpVbBxj4kipEVVJZFdUZQaDERJql0xYGOQrNMQ4JGqJ84BRrtOExjSqo41K hAhNe+bwPGH9/Igiixc4tH07xa7TOy4MyJv/6gpbHy/lW1hqpCAgM5fT/im5/6QF k0tED6vIuc54IWiOmwCnjZiQnJ8uCwEu+cuJ5Exwy9CNERLp5v0y4eG+0E+at9j/ macOg39qf09t53pTqe9dWv5NIi319TeBsKZ2lb0crrQjsbHqk0DAUwgQuoANqLku vA== =kRIv -----END PGP PUBLIC KEY BLOCK----- ]===]) if last_err() then return end print(key)
نوشتن مستقیم دادهها در ترمینال.
print({
some=1,
fancy={
data='structures',
}
})
هشدار:
psl_domain_from_dns_name
دامنه والد را مطابق با فهرست پسوندهای عمومی (public suffix list) برمیگرداند. برای www.a.b.c.d.example.co.uk این مقدار برابر با example.co.uk خواهد بود.
domain = psl_domain_from_dns_name('www.a.b.c.d.example.co.uk')
print(domain == 'example.co.uk')
ایجاد یک محدودکننده نرخ (ratelimit) که در هر y میلیثانیه تنها x بار میتواند عبور کند. این محدودیت برای یک run منفرد بهصورت سراسری بوده و با threadها نیز کار میکند.
-- allow this to pass every 250ms
ratelimit_throttle('foo', 1, 250)
-- allow this to pass not more than 4 times per second
ratelimit_throttle('foo', 4, 1000)
این قابلیت زمانی مفید است که بخواهید اجراهای خود را هماهنگ کنید تا پایینتر از یک آستانه مشخص از درخواستها باقی بمانید.
regex_find
اعمال یک regex روی یک متن. در صورتی که regex مطابقت نداشته باشد nil و در صورت تطابق، گروههای ضبط (capture groups) را برمیگرداند.
m = regex_find(".(.)", "abcdef")
if m == nil then
print('No captures')
end
print(m[1] == 'ab')
print(m[2] == 'b')
regex_find_all
مشابه regex_find، اما تمام تطابقها را برمیگرداند.
m = regex_find_all(".(.)", "abcdef")
print(m[1][1] == 'ab')
print(m[1][2] == 'b')
print(m[2][1] == 'cd')
print(m[2][2] == 'd')
print(m[3][1] == 'ef')
print(m[3][2] == 'f')
semver_match
مقایسه یک نسخه با پیشنیاز نسخه. این تابع میتواند همراه با sn0int_version برای بررسی قابلیتها یا رفتارهای مشخصی استفاده شود.
semver_match('=0.11.2', sn0int_version())
semver_match('>0.11.2', sn0int_version())
semver_match('<0.11.2', sn0int_version())
semver_match('~0.11.2', sn0int_version())
semver_match('^0.11.2', sn0int_version())
semver_match('0.11.2', sn0int_version()) -- synonym for ^0.11.2
semver_match('<=0.11.2', sn0int_version())
semver_match('>=0.11.2', sn0int_version())
semver_match('>=0.4.0, <=0.10.0', sn0int_version())
set_err
دستکاری شیء خطای سراسری (global error object). اگر قصد دارید تابع اصلی run را با یک خطا خاتمه دهید، میتوانید صرفاً یک رشته را برگردانید، اما انتشار آنها از میان توابع مختلف دشوار است. set_err بهطور ویژه خطایی را به شیء خطای سراسری اختصاص میدهد که توسط تمام توابع دیگر rust نیز استفاده میشود.
function foo()
set_err("something failed")
end
foo()
if last_err() then return end
یک آرایهٔ بایتی را با sha1 هش کرده و نتایج را به صورت بایت بازمیگرداند.
hex(sha1("\x00\xff"))
sha2_256
یک آرایهٔ بایتی را با sha2_256 هش کرده و نتایج را به صورت بایت بازمیگرداند.
hex(sha2_256("\x00\xff"))
sha2_512
یک آرایهٔ بایتی را با sha2_512 هش کرده و نتایج را به صورت بایت بازمیگرداند.
hex(sha2_512("\x00\xff"))
sha3_256
یک آرایهٔ بایتی را با sha3_256 هش کرده و نتایج را به صورت بایت بازمیگرداند.
hex(sha3_256("\x00\xff"))
sha3_512
یک آرایهٔ بایتی را با sha3_512 هش کرده و نتایج را به صورت بایت بازمیگرداند.
hex(sha3_512("\x00\xff"))
sleep
برنامهٔ جاری را به تعداد ثانیههای مشخص شده متوقف میکند. این معمولاً تنها برای اشکالزدایی استفاده میشود.
sleep(1)
sn0int_time
زمان کنونی را بر اساس UTC بازمیگرداند. این تابع برای تعیین تاریخ و زمان برای فیلدهای پایگاه دادهٔ DATETIME مناسب است.
now = sn0int_time()
نکته:
همانند sn0int_time است، اما به جای زمان کنونی از یک برچسب زمان یونیکس (unix timestamp) بر حسب ثانیه استفاده میکند. این تابع با time_unix و strptime سازگار است.
time = sn0int_time_from(1567931337)
sn0int_version
رشتهٔ نسخهٔ کنونی sn0int را دریافت میکند. این رشته میتواند به همراه semver_match برای بررسی قابلیتها یا رفتارهای مشخص به کار رود.
info(sn0int_version())
sock_connect
یک اتصال tcp ایجاد میکند.
گزینههای زیر در دسترس هستند:
- tls
- برای فعالسازی tls مقدار را برابر با true قرار دهید (گواهیها اعتبارسنجی میشوند).
- sni_value
- به جای آرگومان host، از یک رشتهٔ سفارشی برای افزونهٔ sni استفاده میکند.
- disable_tls_verify
- خطر: غیرفعالسازی اعتبارسنجی tls. این گزینه تمامی امنیت روی اتصال را غیرفعال میکند. توجه داشته باشید که sn0int همچنان نسبتاً سختگیر است؛ در صورتی که به پشتیبانی از رمزهای (ciphers) ناامن نیاز داشته باشید، با مشکل مواجه خواهید شد.
- proxy
- استفاده از یک پروکسی socks5 در قالب 127.0.0.1:9050. این گزینه تنها در صورتی کار میکند که با تنظیمات سراسری پروکسی تداخلی نداشته باشد.
- connect_timeout
- لغو تلاشهای اتصال tcp پس از n ثانیه.
- read_timeout
- لغو تلاشهای خواندن پس از n ثانیه. از این گزینه میتوان برای بیدار کردن دورهای اتصالها استفاده کرد.
- write_timeout
- لغو تلاشهای نوشتن پس از n ثانیه.
sock = sock_connect("127.0.0.1", 1337, {
tls=true,
})
sock_upgrade_tls
یک اتصال tcp موجود را دریافت کرده و دستتکانی tls را آغاز میکند. گزینهها همانند sock_connect هستند، اما مقدار tls همیشه true در نظر گرفته میشود.
مقدار sni باید به صورت مشخص تنظیم شود، در غیر این صورت افزونهٔ sni غیرفعال خواهد بود.
استفاده از این تابع به صورت ویژه اطلاعات اضافی بازمیگرداند که هنگام استفادهٔ مستقیم از sock_connect با tls=true نادیده گرفته میشوند.
sock = sock_connect("127.0.0.1", 1337, {})
if last_err() then return end
tls = sock_upgrade_tls(sock, {
sni_value='example.com',
})
if last_err() then return end
info(tls)
بهروزرسانی گزینههای یک اتصال موجود:
- read_timeout
- لغو تلاشهای خواندن پس از n ثانیه. این گزینه میتواند برای بیدار کردن دورهای اتصالها استفاده شود.
- write_timeout
- لغو تلاشهای نوشتن پس از n ثانیه.
sock_options(sock, {
read_timeout=3,
})
sock_send
ارسال داده به سوکت.
sock_send(sock, "hello world")
sock_recv
دریافت حداکثر ۴۰۹۶ بایت از سوکت.
x = sock_recv(sock)
sock_sendline
ارسال یک رشته به سوکت. یک خط جدید (newline) بهطور خودکار به انتهای رشته افزوده میشود.
sock_sendline(sock, line)
sock_recvline
دریافت یک خط از سوکت. این خط شامل نویسه خط جدید نیز خواهد بود.
x = sock_recvline(sock)
sock_recvall
دریافت تمام دادهها از سوکت تا رسیدن به EOF.
x = sock_recvall(sock)
sock_recvline_contains
دریافت خطوط از سرور تا زمانی که یک خط شامل needle باشد، سپس بازگرداندن این خط.
x = sock_recvline_contains(sock, needle)
دریافت خطها از سرور تا زمانی که یک خط با عبارت باقاعده (regex) مطابقت پیدا کند، سپس بازگرداندن این خط.
x = sock_recvline_regex(sock, "^250 ")
sock_recvn
دریافت دقیقاً n بایت از سوکت.
x = sock_recvn(sock, 4)
sock_recvuntil
دریافت دادهها تا زمانی که needle پیدا شود، سپس بازگرداندن تمام دادهها شامل needle.
x = sock_recvuntil(sock, needle)
sock_sendafter
دریافت دادهها تا زمانی که needle پیدا شود، سپس نوشتن data در سوکت.
sock_sendafter(sock, needle, data)
sock_newline
بازنویسی خط جدید پیشفرض \n.
sock_newline(sock, "\r\n")
sodium_secretbox_open
استفاده از رمزنگاری متقارن احراز هویت شده برای رمزگشایی یک پیام مشخص.
در لایهٔ درونی، این معادل crypto_secretbox_xsalsa20poly1305 است.
کلید باید ۳۲ بایت باشد، در صورت لزوم key_trunc_pad را ببینید.
انتظار میرود ۲۴ بایت نخست پیام رمزنگاریشده nonce باشد.
plain = sodium_secretbox_open(encrypted, key) if last_err() then return end txt = utf8_decode(plain) if last_err() then return end info(txt)
status
بهروزرسانی برچسب نشانگر پیشرفت.
status('ohai')
یک خط را از stdin میخواند. نویسه خط جدید پایانی حذف نمیشود.
stdin_readline()
نکته:
stdin_read_to_end
ورودی stdin را تا رسیدن به EOF به صورت یک رشته utf-8 میخواند.
stdin_read_to_end()
نکته:
str_find
شاخص بایتی نخستین نویسهای که با الگو مطابقت دارد را بازمیگرداند. این تطابق صراحتاً یک تطابق لفظی (literal) است نه یک الگوی lua.
در صورتی که تطابقی یافت نشود، مقدار nil بازگردانده میشود.
x = str_find('asdf', 'sd')
print(x == 2)
str_replace
تمام موارد تطابق یک الگو در یک رشته را جایگزین میکند. این تطابق صراحتاً یک تطابق لفظی (literal) است نه یک الگوی lua.
اگر تطابقی یافت نشود، یک رونوشت تغییرنیافته بازگردانده میشود.
x = str_replace('this is old', 'old', 'new')
print(x == 'this is new')
strftime
یک برچسب زمانی (timestamp) تولیدشده با time_unix را به یک تاریخ قالببندی میکند؛ نگاه کنید به قوانین strftime.
t = strftime('%d/%m/%Y %H:%M', 1558584994)
strptime
یک تاریخ را به یک برچسب زمانی یونیکس (unix timestamp) تجزیه میکند؛ نگاه کنید به قوانین strftime.
t = strptime('%d/%m/%Y %H:%M', '23/05/2019 04:16')
تبدیل یک عدد به رشته.
time_unix
دریافت زمان کنونی به صورت ثانیههای سپریشده از 1 ژانویه 1970، ساعت 0:00:00 UTC که به عنوان برچسب زمان یونیکس (UNIX timestamp) نیز شناخته میشود. این برچسب زمان را میتوان با استفاده از strftime قالببندی کرد.
now = time_unix()
url_decode
تجزیه یک رشته پرسمان (query string) به یک نگاشت (map). برای رمزگشایی درصدی خام url_unescape را ببینید.
v = url_decode('a=b&c=d')
print(v['a'] == 'b')
print(v['c'] == 'd')
url_encode
کدگذاری یک نگاشت (map) به یک رشته پرسمان (query string). برای کدگذاری درصدی خام url_escape را ببینید.
v = url_encode({
a='b',
c='d',
})
print(v == 'a=b&c=d')
url_escape
اعمال گریز نشانی وب (url escaping) بر روی یک رشته.
v = url_escape('foo bar?')
print(v == 'foo%20bar%3F')
url_join
پیوستن یک پیوند نسبی به یک پیوند مطلق. اگر هر دو پیوند مطلق باشند، فقط پیوند نخست بازگردانده میشود:
x = url_join('https://example.com/x', '/foo')
print(x == 'https://example.com/foo')
x = url_join('https://example.com/x', 'https://github.com/')
print(x == 'https://github.com/')
url_parse
تجزیه یک url به مؤلفههای آن. مؤلفههای زیر بازگردانده میشوند:
- scheme
- host
- port
- path
- query
- fragment
- params
url = url_parse('https://example.com')
print(url['scheme'] == 'https')
print(url['host'] == 'example.com')
print(url['path'] == '/')
حذف کدگذاری نشانی وب (URL escaping) از یک رشته.
v = url_unescape('foo%20bar%3F')
print(v == 'foo bar?')
utf8_decode
رمزگشایی فهرستی از بایتها/اعداد به یک رشته. ممکن است اجرای این تابع با شکست مواجه شود.
x = utf8_decode({65, 65, 65, 65})
if last_err() then return end
print(x == 'AAAA')
warn
ثبت یک پیام هشدار در ترمینال.
warn('ohai')
warn_once
ثبت یکبارهٔ یک هشدار در ترمینال. این قابلیت میتواند برای نمایش یک هشدار به کاربر استفاده شود، بدون اینکه همان هشدار برای تکتک ساختارهای در حال پردازش در طول یک اجرای run تکرار گردد.
warn_once('ohai')
warn_once('ohai')
ws_connect
ایجاد یک اتصال websocket. قالب آدرس وب به صورت ws://example.com/asdf است، همچنین از wss:// نیز پشتیبانی میشود.
گزینههای زیر در دسترس هستند:
- headers
- نگاشتی از سرآیندهای (headers) اضافی که باید برای درخواست تنظیم شوند.
- proxy
- استفاده از یک پروکسی socks5 در قالب 127.0.0.1:9050. این گزینه تنها در صورتی کار میکند که با تنظیمات سراسری پروکسی تداخلی نداشته باشد.
- connect_timeout
- لغو تلاشها برای برقراری اتصال tcp پس از n ثانیه.
- read_timeout
- لغو تلاشهای خواندن پس از n ثانیه. این گزینه میتواند برای فعالسازی دورهای اتصالها استفاده شود.
- write_timeout
- لغو تلاشهای نوشتن پس از n ثانیه.
sock = ws_connect("wss://example.com/asdf", {})
بهروزرسانی گزینههای یک اتصال موجود:
- read_timeout
- تلاشهای خواندن را پس از n ثانیه لغو میکند. از این مورد میتوان برای بیدار کردن دورهای اتصالات استفاده کرد.
- write_timeout
- تلاشهای نوشتن را پس از n ثانیه لغو میکند.
ws_options(sock, {
read_timeout=3,
})
ws_recv_text
منتظر میماند تا سرور یک فریم متنی ارسال کند. دریافت یک فریم باینری خطا در نظر گرفته میشود. به درخواستهای Ping بهطور خودکار پاسخ داده میشود.
msg = ws_recv_text(sock)
ws_recv_binary
منتظر میماند تا سرور یک فریم باینری ارسال کند. دریافت یک فریم متنی خطا در نظر گرفته میشود. به درخواستهای Ping بهطور خودکار پاسخ داده میشود.
msg = ws_recv_binary(sock)
ws_recv_json
مشابه ws_send_text است، اما بهطور خودکار json_decode را روی پاسخ اجرا میکند.
msg = ws_recv_json(sock)
ws_send_text
ارسال یک فریم متنی روی اتصال websocket.
ws_send_text(sock, "ohai!")
ws_send_binary
ارسال یک فریم باینری روی اتصال websocket.
ws_send_binary(sock, "\x00\x01\x02")
شیء را بهصورت یک رشتهٔ json کدگذاری کرده و آن را در قالب یک فریم متنی بر روی اتصال websocket ارسال میکند.
ws_send_text(sock, {
foo="ohai!",
x={
y={1,3,3,7},
},
})
x509_parse_pem
یک گواهی کدگذاریشده با pem را تجزیه میکند. این تابع ممکن است ناموفق باشد.
x = x509_parse_pem([[-----BEGIN CERTIFICATE----- MIID9DCCA3qgAwIBAgIQBWzetBRl/ycHFsBukRYuGTAKBggqhkjOPQQDAjBMMQsw CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSYwJAYDVQQDEx1EaWdp Q2VydCBFQ0MgU2VjdXJlIFNlcnZlciBDQTAeFw0xODAzMzAwMDAwMDBaFw0yMDAz MjUxMjAwMDBaMGwxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMN U2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEdMBsGA1UE AwwUKi5jbG91ZGZsYXJlLWRucy5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC AASyRQsxrFBjziHmfDQjGsXBU0WWl3oxh7vg6h2V9f8lBMp18PY/td9R6VvJPa20 AwVzIJI+dL6OSxviaIZEbmK7o4ICHDCCAhgwHwYDVR0jBBgwFoAUo53mH/naOU/A buiRy5Wl2jHiCp8wHQYDVR0OBBYEFN+XTeVDs7BBp0LykM+Jf64SV4ThMGMGA1Ud EQRcMFqCFCouY2xvdWRmbGFyZS1kbnMuY29thwQBAQEBhwQBAAABghJjbG91ZGZs YXJlLWRucy5jb22HECYGRwBHAAAAAAAAAAAAERGHECYGRwBHAAAAAAAAAAAAEAEw DgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBp BgNVHR8EYjBgMC6gLKAqhihodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1l Y2MtZzEuY3JsMC6gLKAqhihodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc3NjYS1l Y2MtZzEuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEW HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMHsGCCsGAQUF BwEBBG8wbTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEUG CCsGAQUFBzAChjlodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRF Q0NTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADAKBggqhkjOPQQDAgNo ADBlAjEAjoyy2Ogh1i1/Kh9+psMc1OChlQIvQF6AkojZS8yliar6m8q5nqC3qe0h HR0fExwLAjAueWRnHX4QJ9loqMhsPk3NB0Cs0mStsNDNG6/DpCYw7XmjoG3y1LS7 ZkZZmqNn2Q8= -----END CERTIFICATE----- ]]) if last_err() then return end print(x)
xml_decode
یک مقدار lua را از یک سند xml رمزگشایی میکند.
x = xml_decode('<body><foo fizz="buzz">bar</foo></body>')
if last_err() then return end
body = x['children'][1]
foo = body['children'][1]
print(foo['attrs']['fizz'])
print(foo['text'])
xml_named
یک عنصر فرزند نامگذاریشده را از یک عنصر والد دریافت میکند.
x = xml_decode('<body><foo fizz="buzz">bar</foo></body>')
if last_err() then return end
body = x['children'][1]
foo = xml_named(body, 'foo')
if foo ~= nil then
print(foo)
end
کپیرایت و تکثیر (COPYRIGHT)
2018-2020, kpcyrd
| July 17, 2025 |