پرش به محتوای اصلی
پرش به محتوای مقاله

کتابخانه Mojibake استانداردهای یونیکد ۱۷ را با صفر وابستگی پیاده کرد

·۲۶ تیر ۱۴۰۵۲۷ دقیقه مطالعه
کاراکترهای یونیکد ۱۷ به‌صورت نادرست در C نمایش داده شده‌اند
کاراکترهای یونیکد ۱۷ به‌صورت نادرست در C نمایش داده شده‌اند
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

ارائه دسترسی کامل به استاندارد یونیکد ۱۷.۰ در قالب دو فایل C/C++ بدون هیچ وابستگی خارجی، در حالی که اکثر ابزارهای مشابه یا ناقص هستند یا نیاز به نصب چارچوب‌های حجیم دارند.

تصور کنید برای پیاده‌سازی کامل استاندارد یونیکد ۱۷.۰، به‌جای درگیر شدن با هزارتوی وابستگی‌های نرم‌افزاری، تنها دو فایل به پروژه خود اضافه کنید. این وعدهٔ Mojibake است؛ کتابخانه‌ای مستقل که با زبان C11 نوشته شده و با C++17 سازگاری کامل دارد. این کتابخانه تحت لایسنس MIT منتشر شده و هدف آن حذف کامل بار اضافی زمان اجرا (Runtime baggage) است که معمولاً با پردازش متون استاندارد و مطابق با آخرین نسخه‌های یونیکد همراه است.

مدیریت متون جهانی در زبان C معمولاً نیازمند کتابخانه‌های عظیمی مثل ICU است که ادغام آن‌ها در پروژه‌ها به‌دلیل حجم زیاد و پیچیدگی‌های پیکربندی، بسیار دشوار و سنگین است. این موضوع همیشه یک نقطهٔ ضعف و چالش شناخته شده برای برنامه‌نویسان سیستم‌هایی بوده است که به کنترل دقیق، سبک و در عین حال دقیق روی کاراکترها نیاز دارند. Mojibake این مشکل را با ارائه یک «آمالگامات» (Amalgamation) — یعنی تنها دو فایل mojibake.c و mojibake.h — حل کرده است که به هیچ وابستگی خارجی نیاز ندارد.

بر اساس بررسی منابع فنی، این ابزار روی تمامی سیستم‌عامل‌های مدرن از جمله لینوکس، macOS، FreeBSD، OpenBSD، NetBSD و ویندوز ۱۰ و ۱۱ بدون نیاز به هیچ پیش‌نیازی اجرا می‌شود. همان‌طور که در تحلیل‌های پیشین ما درباره‌ی بهینه‌سازی لایه‌های زیرین نرم‌افزار اشاره کردیم، حذف وابستگی‌ها (Dependencies) کلید افزایش پایداری در سیستم‌های حساس است. Mojibake دقیقاً همین مسیر را طی کرده است تا توسعه‌دهندگان را از «جهنم وابستگی‌ها» در پردازش متن نجات دهد.

تحول متن و نرمال‌سازی

این کتابخانه تمامی الگوریتم‌های اصلی استاندارد یونیکد را پیاده کرده و تمام الزامات تطبیق (Unicode Conformance Requirements) را برآورده می‌کند. تابع mjb_normalize عملیات نرمال‌سازی را در چهار حالت NFC، NFD، NFKC و NFKD مدیریت می‌کند. برای مثال در حالت NFC، توالی e + ◌́ (U+0301 COMBINING ACUTE ACCENT) به‌طور خودکار به کاراکتر واحد é (U+00E9) تبدیل می‌شود.

برای برنامه‌نویسانی که سرعت اولویت دارند، سازوکار «بررسی سریع» (mjb_string_is_normalized) اجازه می‌دهد اگر رشته از قبل نرمال شده است، از مراحل پردازش کامل و هزینه‌بر عبور کنند. خروجی این بررسی یک مقدار از نوع mjb_quick_check_result است که وضعیت را به سه حالت تقسیم می‌کند: MJB_QC_YES به معنای نرمال بودن، MJB_QC_NO به معنای عدم نرمال بودن، و MJB_QC_MAYBE که سیگنال می‌دهد برای تصمیم‌گیری نهایی، یک گذر کامل (Full Pass) از متن همچنان مورد نیاز است. این فرآیند کاملاً مطابق با استانداردهای UAX #15 برای یونیکد ۱۷.۰.۰ است.

تغییر وضعیت حروف (Case conversion) توسط تابع mjb_case انجام می‌شود که تبدیل‌ها را به حروف بزرگ (Uppercase)، کوچک (Lowercase) و وضعیت Titlecase مدیریت می‌کند. این فرآیند شامل نگاشت‌های شرطی و موارد خاص (Special-casing) است. در پیاده‌سازی Titlecase، از مرزبندی‌های کلمات مطابق با استاندارد UAX #29 استفاده شده تا تضمین شود اولین کاراکتر دارای حالت (Cased) در هر بخش از کلمه به صورت Titlecase تبدیل شده و کاراکترهای بعدی کوچک شوند.

تنظیمات حروف بر اساس محل یا همان Locale است که با تابع mjb_locale_set در سطح سراسریِ فرآیند تعیین می‌شود. پیش‌فرض این تنظیم روی MJB_LOCALE_EN (انگلیسی) است. با این حال، پشتیبانی تخصصی برای MJB_LOCALE_TR و MJB_LOCALE_AZ برای مدیریت حروف I نقطه‌دار در زبان‌های ترکی و آذربایجانی و همچنین Case-folding مخصوص اقوام ترک فراهم شده است. همچنین MJB_LOCALE_LT قواعد خاص نقطه‌گذاری در زبان لیتوانیایی را اعمال می‌کند. این دقت باعث می‌شود تبدیل‌های خاص، مانند تبدیل سیگمای یونانی (U+0041) به سیگمای کوچک (U+03C3)، به‌درستی انجام شود.

در سطح کدپوینت (Codepoint)، توسعه‌دهندگان می‌توانند از توابع هدفمندتری استفاده کنند: mjb_codepoint_to_lowercase برای تبدیل به حروف کوچک، mjb_codepoint_to_uppercase برای حروف بزرگ و mjb_codepoint_to_titlecase برای وضعیت Titlecase. برای مثال، فراخوانی mjb_codepoint_to_uppercase(0x00E9) برای کاراکتر 'é' مقدار U+00C9 را برمی‌گرداند و فراخوانی mjb_codepoint_to_titlecase(0x01F3) برای 'dz' مقدار U+01F2 را بازمی‌گرداند.

برای کارهای مربوط به شناسه‌ها (Identifiers)، تابع mjb_nfkc_casefold نگاشت‌های استاندارد NFKC_Casefold را اعمال کرده و نتیجه را به فرم NFC نرمال می‌کند. این عملیات باعث حذف کدپوینت‌های «پیش‌فرض قابل چشم‌پوشی» (Default-ignorable) شده و Folding سازگاری را انجام می‌دهد که برای مقایسه دقیق شناسه‌ها حیاتی است. برای نمونه، این تابع واژه آلمانی "Straße" را به "strasse" تبدیل می‌کند.

فیلترگذاری و تجزیه متن

علاوه بر تغییرات ساختاری، Mojibake تابع mjb_string_filter را ارائه می‌دهد. این تابع به توسعه‌دهندگان اجازه می‌دهد تا هم‌زمان با نرمال‌سازی متن، کاراکترهای کنترلی، فاصله‌ها یا اعداد را حذف کنند. گزینه‌های فیلتر شامل MJB_FILTER_COLLAPSE_SPACES است که چندین فضای خالی متوالی (مانند \t\t\n\n) را به یک تک-فاصله تبدیل می‌کند. همچنین فیلتر MJB_FILTER_CONTROLS برای حذف کاراکترهای غیرقابل چاپ به کار می‌رود. برای مثال، رشته‌ای حاوی \x1\x2\t\n\v\f\r\x1f اگر با این فیلتر پردازش شود، تنها کاراکترهای فضای سفید استاندارد مثل \t\n\v\f\r را حفظ می‌کند.

یک فیلتر تخصصی به نام MJB_FILTER_LIMIT_COMBINING برای مقابله با متن‌های سبک «Zalgo» طراحی شده است. این فیلتر علامت‌های ترکیبی را پس از رسیدن به حد مجاز MJB_FILTER_MAX_COMBINING_MARKS در یک اجرای متوالی حذف می‌کند. این کار باعث می‌شود اکسنت‌های معمولی حفظ شوند اما از انباشت بیش از حد علامت‌ها که باعث به‌هم‌ریختگی بصری می‌شود، جلوگیری گردد.

تحلیل فنی و امنیت

Mojibake فراتر از تبدیل‌های ساده، قابلیت‌های تحلیل عمیق متن را فراهم کرده است:

  • پایگاه داده کاراکترها: دسترسی کامل به تمام ویژگی‌های پایگاه داده کاراکترهای یونیکد (UCD) از طریق تابع mjb_codepoint_character فراهم است. این تابع یک رکورد mjb_character شامل دسته (Category)، اسکریپت، بلوک، صفحه (Plane)، مقدار عددی و نام کاراکتر را پر می‌کند. ویژگی‌ها را می‌توان به صورت باینری (مانند mjb_codepoint_property_binary برای ویژگی MJB_PR_ALPHABETIC) یا به صورت عدد صحیح (مانند mjb_codepoint_property_int برای MJB_PR_SCRIPT) استعلام کرد.
  • مقادیر عددی: تابع mjb_codepoint_numeric_value مقادیر اعشاری، ارقام و رشته‌های عددی را استخراج می‌کند. برای مثال، U+0031 (رقم 1) مقدار اعشاری 1 را برمی‌گرداند، در حالی که U+00BD (کسر ۱/۲) رشته عددی "1/2" را بازمی‌گرداند. اگر کدپoyne‌ای مقدار عددی نداشته باشد، فیلدهای اعشاری و رقمی آن روی MJB_NUMBER_NOT_VALID (عدد -1) تنظیم می‌شود.
  • اعتبارسنجی: توسعه‌دهندگان می‌توانند با mjb_codepoint_is_valid صحت یک کدپوینت (مثلاً U+10FFFD) را بررسی کنند. همچنین توابعی برای تشخیص اینکه آیا یک کاراکتر گرافیکی است (mjb_codepoint_is_graphic) یا یک ایدئوگراف CJK است (mjb_codepoint_is_cjk_ideograph) یا ایدئوگراف توسعه‌یافته CJK است (mjb_codepoint_is_cjk_ext) وجود دارد.
  • تحلیل صفحه (Plane): توابعی مانند mjb_codepoint_plane صفحه یونیکد را شناسایی می‌کنند (مثلاً U+1F600 در صفحه SMP قرار دارد). توسعه‌دهندگان می‌توانند صفحات را با mjb_plane_is_valid اعتبارسنجی کرده و نام آن‌ها را با mjb_plane_name (مانند "Basic Multilingual Plane") دریافت کنند.
  • قطعه‌بندی (Segmentation): پیاده‌سازی کامل UAX #29 و UAX #14 برای شناسایی خوشه‌های گرافم (Grapheme Clusters)، کلمات، جملات و فرصت‌های شکست خط. توابعی مانند mjb_break_grapheme_cluster اجازه می‌دهند توسعه‌دهنده روی کاراکترهایی که کاربر به‌صورت بصری ادراک می‌کند پیمایش کند. برای مثال، رشته «e + اکسنت ترکیب‌شونده» (U+0065 U+0301) از دو کدپوینت تشکیل شده اما تنها یک خوشه گرافم محسوب می‌شود.
  • جزئیات شکست متن: توابع mjb_break_word و mjb_break_sentence امکان کشف مرزهای کلمات و جملات را می‌دهند. برای ورودی "Hello. Goodbye."، تابع mjb_break_sentence حدود ۱۵ بایت مرز را شناسایی می‌کند.
  • برش متون (Truncation): کتابخانه تابع mjb_truncate را برای برش متون با آگاهی از گرافم (مثلاً برش "A🇮🇹Z" به ۲ گرافم که ۹ بایت اشغال می‌کند)، mjb_truncate_word برای برش با آگاهی از قطعه‌بندی کلمات و mjb_truncate_word_width برای محدود کردن متن بر اساس عرض ستونی فراهم کرده است.
  • متون دوجهتی (Bidi): پشتیبانی کامل از الگوریتم یونیکد برای متون دوجهتی (UAX #9). این شامل پرداخت پاراگراف‌ها از طریق mjb_bidi_resolve (مثلاً تبدیل "abc אבג" به ۷ کدپوینت)، مرتب‌سازی مجدد خطوط با mjb_bidi_reorder_line و استخراج تکه‌های متن از طریق mjb_bidi_line_runs برای مدیریت صحیح متون ترکیبی راست‌به-چپ و چپ‌به-راست است.
  • امنیت: شناسایی کاراکترهای مشابه یا Confusable از طریق mjb_confusable_skeleton که اسکلت‌های متنی را بر اساس UTS #39 تولید می‌کند. این فرآیند شامل اعمال الگوریتم Bidi L4، نرمال‌سازی NFD، حذف موارد پیش‌فرض قابل چشم‌پوشی و جایگزینی پروتوتایپ‌ها از فایل confusables.txt است. تابع mjb_string_is_confusable تشخیص می‌دهد آیا دو رشته از نظر بصری شبیه هستند یا خیر؛ مثلاً تشخیص تفاوت بین "good" انگلیسی و "gооd" که در آن از حرف 'о' سیریلیک استفاده شده است.
  • پشتیبانی از ایموجی: پیاده‌سازی UTS #51 برای تشخیص ایموجی‌های RGI از طریق mjb_string_is_rgi_emoji (مثلاً برای پرچم ایتالیا 🇮🇹)، تحلیل توالی‌ها با mjb_string_emoji_sequence و بررسی ویژگی‌های خاص مانند اصلاح‌کننده‌های پوستی (mjb_codepoint_is_emoji_modifier برای U+1F3FD)، نحوه نمایش (mjb_codepoint_is_emoji_presentation برای 0x1F600) یا اجزای تشکیل‌دهنده مانند ZWJ (U+200D) از طریق mjb_codepoint_is_emoji_component.
  • عرض نمایش: پشتیبانی از UAX #11 (East Asian Width). تابع mjb_display_width ستون‌های ترمینال را با در نظر گرفتن کاراکترهای عریض (مانند U+754C 界 که MJB_EAW_WIDE است) و علامت‌های ترکیبی محاسبه می‌کند. همچنین mjb_truncate_width اجازه برش متن را با آگاهی از عرض در زمینه‌هایی مانند MJB_WIDTH_CONTEXT_WESTERN می‌دهد.

هوشمندی محلی و زبان کره‌ای

Mojibake منطق بسیار خاصی برای خط کره‌ای پیاده کرده است. توابعی برای شناسایی اجزای Jamo فراهم شده است: mjb_codepoint_is_hangul_l برای Jamoهای پیشرو (مانند U+1100)، mjb_codepoint_is_hangul_v برای مصوت‌ها (مانند U+1161) و mjb_codepoint_is_hangul_t برای Jamoهای پایانی (مانند U+11A8).

توسعه‌دهندگان می‌توانند تجزیه سیلاب‌های کره‌ای را با mjb_hangul_syllable_decomposition (مثلاً U+AC01 که با U+1100 تجزیه می‌شود) یا ترکیب آن‌ها را با mjb_hangul_syllable_composition انجام دهند. همچنین تابع mjb_hangul_syllable_name نام رسمی یک سیلاب را بازمی‌گرداند، مانند "HANGUL SYLLABLE GAG" برای کدپوینت U+AC01.

برای نیازهای گسترده‌تر زبانی، تابع mjb_locale_parse تگ‌های زبانی BCP 47 (مانند "sr-Latn-RS") را به‌طور سخت‌گیرانه تجزیه می‌کند و آن‌ها را به بخش‌های زبان، اسکریپت، منطقه، گونه و پسوندها تقسیم می‌کند. تگ‌های نادرست با یک خطای دقیق در شیء mjb_error رد می‌شوند.

ادغام و عملکرد

این کتابخانه از طیف وسیعی از رمزگذاری‌ها شامل UTF-8، UTF-16 (LE/BE) و UTF-32 (LE/BE) پشتیبانی می‌کند. تابع mjb_string_convert_encoding تبدیل‌ها را مدیریت می‌کند. برای مثال، تبدیل "café" از UTF-8 منجر به تولید ۸ بایت در فرمت UTF-16LE می‌شود. در ورودی‌های عمومی UTF-16/UTF-32، کتابخانه از BOM (Byte Order Mark) به عنوان امضا برای تشخیص ترتیب بایت‌ها استفاده می‌کند و در صورت نبود آن، ورودی را رد می‌کند.

تشخیص رمزگذاری توسط mjb_string_encoding انجام می‌شود که طرح‌های مشتق شده از BOM را گزارش می‌کند. در مواقعی که فلگ‌ها هم‌پوشانی دارند — مثلاً یک BOM مربوط به UTF-32LE که پیشوندی شبیه UTF-16LE دارد — کتابخانه اولویت را به UTF-32 می‌دهد. یک BOM مربوط به UTF-16LE یعنی \xFF\xFE به صورت MJB_ENC_UTF_16 | MJB_ENC_UTF_16LE شناسایی می‌شود.

برای کوچک نگه داشتن حجم باینری نهایی، توسعه‌دهندگان می‌توانند از فلگ‌های ویژگی در زمان ساخت (Build-time) استفاده کنند. برای مثال، غیرفعال کردن MJB_FEATURE_CHARACTER_NAMES حجم خروجی را حدود ۳۰٪ کاهش می‌دهد، زیرا جداول نام کاراکترها کامپایل نمی‌شوند و مقدار mjb_character.name به صورت ساده "Codepoint U+XXXX" گزارش می‌شود. این تنظیم از طریق CMake با پارامتر -DMJB_FEATURE_CHARACTER_NAMES=OFF یا از طریق Makefile قابل پیکربندی است.

تست‌ها در این پروژه یک رکن اساسی هستند. Mojibake از مجموعه تست Attractor استفاده کرده و بیش از ۱.۵ میلیون Assertion (تأییدیه) را با موفقیت پشت سر گذاشته است. این شامل مجموعه‌های تطبیق رسمی یونیکد برای تمام الگوریتم‌های پشتیبانی شده است. برای اطمینان از پایداری در برابر ورودی‌های بایتی غیرقابل‌اعتماد، پروژه با libFuzzer آزمایش شده و توسط AddressSanitizer و UBSan تأیید شده است.

برای توسعه‌دهندگان C++، یک Wrapper در مسیر src/cpp/mojibake.hpp فراهم شده است. همچنین یک API برای WASM و TypeScript در src/api برای ابزارهای مبتنی بر مرورگر و یک ابزار CLI اختصاصی در src/shell برای تست‌های محیط شل وجود دارد. ابزار CLI اجازه بررسی‌های سریع را می‌دهد؛ مثلاً اجرای mojibake nfc $'Cafe\u0301' برای مشاهده خروجی NFC یا mojibake emoji "☺️" برای تحلیل توالی ایموجی‌ها به صورت [1] Basic, [2] Fully-qualified.

از آنجا که Mojibake از تخصیص‌کننده‌های حافظه سفارشی (Custom Allocators) از طریق mjb_set_memory_functions پشتیبانی می‌کند، برای سیستم‌های جاسازی‌شده (Embeddable) که در آن‌ها تکه تکه شدن حافظه (Fragmentation) یک نگرانی است، کاملاً مناسب است. کاربران می‌توانند توابع پیش‌فرض را با alloc_fn، realloc_fn و free_fn خود جایگزین کنند. همچنین وضعیت کتابخانه را می‌توان با mjb_shutdown بازنشانی کرد.

مدیریت حافظه برای نتایج از طریق mjb_result_free انجام می‌شود که بافرهای خروجی تخصیص‌یافته را به‌صورت ایمن آزاد می‌کند. برای مثال، اشیاء mjb_result حاصل از mjb_normalize یا mjb_collation_key باید آزاد شوند تا از نشت حافظه (Memory Leak) جلوگیری شود. ساختار mjb_result ردیابی می‌کند که آیا خروجی واقعاً تغییر یافته (transformed) است یا خیر تا از تخصیص‌های غیرضروری جلوگیری شود.

توابع کمکی اضافی مانند mjb_string_length به توسعه‌دهندگان اجازه می‌دهد تعداد واقعی کدپوینت‌های یونیکد را به جای تعداد بایت‌ها بشمارند. برای مثال، رشته "文字化け" در UTF-8 دارای ۱۲ بایت است اما به‌درستی به عنوان ۴ کاراکتر شناسایی می‌شود. بررسی‌های ساده‌ای مانند mjb_string_is_ascii و mjb_string_is_utf8 اعتبارسنجی سریع بافرهای ورودی را فراهم می‌کنند.

این تغییر رویکرد به سمت آمالگامات تک-فایلی و به‌شدت بهینه‌شده، نشان‌دهنده فاصله گرفتن از رویکرد «همه چیز در یک جا» (Everything-and-the-kitchen-sink) در کتابخانه‌های قدیمی است. با ارائه یک ابزار کاملاً مطابق با استاندارد اما با کمترین اثر (Footprint)، Mojibake مانع ورود توسعه‌دهندگان برای تبدیل یونیکد به یک شهروند درجه یک در اپلیکیشن‌های سطح پایین (Low-level) را از بین برده است.

اگر در حال طراحی یک کامپایلر یا پارسر هستید، اکنون می‌توانید از تابع mjb_string_is_identifier برای اعتبارسنجی XID/ID مطابق با UAX #31 بدون وارد کردن یک فریم‌ورک عظیم استفاده کنید. این امکان را فراهم می‌کند تا به‌طور دقیق بررسی کنید که آیا یک رشته با یک کاراکتر شناسایی معتبر شروع می‌شود (mjb_codepoint_is_id_start یا mjb_codepoint_is_xid_start) و با کاراکترهای ادامه معتبر، چه در پروفایل DEFAULT و چه در NFKC، ادامه می‌یابد.

گام بعدی شما

  • اگر در حال طراحی کامپایلر یا پارسر هستید، از تابع mjb_string_is_identifier برای اعتبارسنجی شناسه‌ها مطابق UAX #31 استفاده کنید.
  • برای کاهش حجم نهایی اپلیکیشن، فلگ MJB_FEATURE_CHARACTER_NAMES را در CMake غیرفعال کنید.
  • ابزار CLI را برای بررسی سریع خروجی‌های NFC یا تحلیل توالی ایموجی‌ها تست کنید.

این کتابخانه تنها بخشی از زنجیره بهینه‌سازی است؛ برای درک چالش‌های پردازش متن در مقیاس بزرگ، به تحلیل ما درباره‌ی توکن‌سازی در مدل‌های زبانی مراجعه کنید.

چرا این موضوع مهم است؟

این ابزار با حذف وابستگی‌های سنگین، اعتبار و پایداری برنامه‌هایی که با متون جهانی سروکار دارند را بالا می‌برد. تخصص Mojibake در رعایت دقیق استانداردهای UAX و UTS باعث می‌شود توسعه‌دهندگان بدون نیاز به تخصص عمیق در یونیکد، متن‌های امن و استاندارد تولید کنند.

تأثیر برای ایران

این کتابخانه برای توسعه‌دهندگان ایرانی که روی ابزارهای پردازش زبان فارسی (مانند نرم‌افزارهای تایپ یا پارسرهای متنی) کار می‌کنند، جایگزینی سبک و رایگان برای کتابخانه‌های تجاری یا سنگین است.

·نگاه ما
تحریریه دات‌هوش

روند بازگشت به کتابخانه‌های تک-فایلی (Single-header/Amalgamation) در مقابل اکوسیستم‌های حجیمی مثل ICU، نشان‌دهنده نیاز مبرم توسعه‌دهندگان سیستم به کنترل دقیق بر حافظه و حذف وابستگی‌های زنجیره‌ای است. Mojibake با ترکیب استانداردهای سخت‌گیرانه یونیکد ۱۷ و سادگی در نصب، عملاً مانع ورود به دنیای پیچیده پردازش متن را برای پروژه‌های سطح پایین (Low-level) از بین می‌برد. این رویکرد، به ویژه در محیط‌های Embedded و سیستم‌های با منابع محدود، یک پیروزی عملیاتی است.

منابع

این گزارش با خط‌لولهٔ خودکار دات‌هوش از منابع معتبر جهانی تدوین و زیر نظر تحریریه منتشر شده است. روش کار ما

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.