رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران

پرچمداران

  1. کامبیز اسدزاده

    کامبیز اسدزاده

    بنیـــان گذار


    • امتیاز

      8

    • تعداد ارسال ها

      201


  2. فرهاد شیری

    فرهاد شیری

    مدیران مرجع


    • امتیاز

      3

    • تعداد ارسال ها

      52



مطالب محبوب

در حال نمایش مطالب دارای بیشترین امتیاز در پنجشنبه, 15 آذر 1397 در همه بخش ها

  1. 5 امتیاز

    نگارش 5.12.0

    42 دریافت

    کیوت (به انگلیسی: Qt) مجموعه‌ای از کتابخانه‌ها و سرآیندهای نوشته‌شده به زبان سی++ است که به برنامه‌نویس امکان توسعه آسان نرم‌افزارهای کاربردی را می‌دهد. کیوت شامل چندین کلاس برای کار با واسط گرافیکی، چندرسانه، ابزارهای پایگاه‌داده، شبکه و … است. نرم‌افزارهای نوشته شده با ابزار کیوت قادرند تا با استفاده از یک کامپایلر زبان سی‌پلاس‌پلاس برای طیف وسیعی از سیستم‌عامل‌ها از جمله گنو/لینوکس (نسخه‌های رومیزی و وسیله‌های قابل حمل)، ویندوز، ویندوز CE، مک‌اواس و … همگردانی شوند. بدین ترتیب حمل نرم‌افزار نوشته شده بدون تغییر در متن کد نوشته شده امکان‌پذیر است. از کیوت در زبان‌های برنامه‌نویسی متعددی مانند سی++ و جاوا و پایتون می‌توان استفاده‌کرد. جهت مشاهده‌ی مباحث مرتبط با این کتابخانه به این بخش مراجعه کنید.

    رایگان

  2. 2 امتیاز
    این تاپیک جهت معرفی و اطلاع رسانی در رابطه با اهداف نسخه‌های جدید، به‌روز‌رسانی‌ها، تاریخ انتشار و موارد مرتبط با آن ایجاد شده است. در این تاپیک به موضوعات مرتبط خواهیم پرداخت. جهت شروع نسخه‌ی ۵.۱۲.۰ کیوت با پشتیبانی LTS را معرفی می‌کنیم. همانطور که می‌دانید کمپانی و تیم توسعه‌دهنده با فعالیت‌های بسیار زیاد خود مُدام در حال به‌روز رسانی و حل مشکلات بازخورد شده از سمت کاربران برای این کتابخانه هستند. بر خلاف نسخه‌های پیشین نسخه‌های سری ۵ با به‌روز‌رسانی‌های پی‌در‌پر مواجه شده است که شاید این بزرگترین تمایز تیم توسعه دهنده در نسخه‌های قبلی است. کتابخانه‌ی کیوت معمولاً در نسخه‌های اصلی از ویژگی‌ها و تغییرات چشمگیری مواجه می‌شود که می‌توان آن‌ها را در تغییرات یا افزوده شدن به ماژول‌های هسته، فرعی و افزونه‌های آن اشاره کرد. البته به این مورد نیز باید اشاره کنیم که این به‌روز‌رسانی‌ها تنها برای خود کتابخانه نبوده و معمولاً محیط توسعه‌ی آن نیز همراه خود به‌روز‌رسانی و حتی به صورت جداگانه منتشر می‌شود که در اینجا تاپیک مخصوص آن آورده شده است. از آنجایی که انتظار می‌رود کیوت در نسخه‌ی ۵.۱۲.۰ با به‌روز‌رسانی‌های اساسی آمده است. یکی از مهمترین آن‌ها تغییر بر روی کامپایلر‌ها و پشتیبانی کامل از استاندارد‌های جدید C++ است. در این نسخه کامپایلر‌های GCC به نسخه‌ی ۸ و کامپایلر‌های Clang به نسخه‌ی ۷ و مهمتر از همه در محیط ویندوز به‌روز رسانی MinGW به نسخه‌ی ۷ بوده است. البته ناگفته نماند با توجه به تغییرات اخیر گوگل در NDK که اعلام کرده است کامپایلر پیشفرض GCC به Clang تغییر کرده است این تغییر نیز در کیوت اعمال و با هماهنگی ۱۰۰٪ از ویژگی‌های جدید توسعه اندروید هماهنگ شده است. بنابراین شما در بخش کیت‌ها شاهد وجود کامپایلر‌های متعددی خواهید بود که به‌روز رسانی شده اند. نکته‌ی مهم برای توسعه دهندگان ویندوز : اگر به خاطر داشته باشید در نسخه‌های ۵.۱۰.۰ به بعد کامپایلر ۳۲ بیتی MSVC به طور غیر منتظره‌ای حذف شده بود که با بازخورد کاربران روبرو و در نهایت در این نسخه نسخه‌ی ۳۲ بیتی کامپایلر MSVC افزوده شده است. مهمترین به‌روزرسانی‌های کیوت ۵.۱۲.۰ ویژگی‌های اضافه شده به هسته: افزوده شدن ویژگی جدید CBOR به عنوان فرمت جدید همانند JSon برای سریالیز داده‌ها. افزوده شدن متد hashLength برای QCryptographicHash که طول خروجی هَش شده را بر می‌گرداند. افزوده شدن متد wildcardToRegularExpression به QRegularExpression جهت معرفی راحت‌تر کد کاربر. افزوده شدن متد anchoredPattern به QRegularExpression جهت پیاده سازی تطبیق کد کاربر. افزوده شدن QRegularExpression برای کلاس QSortFilterProxyModel ویژگی‌ها و تغییرات در QtGui افزوده شدن پشتیبانی از ویژگی Windows UI Automation در WinRT QPA برای برنامه‌های مبتنی بر UWP که آن را قادر می‌سازد تا با ابزار‌های قابل دسترس در سمت UI دسترسی داشته باشند. جایگزین شدن ویژگی‌های مرتبط با دستگاه‌های ورودی mouse، touchpad، touchscreen و tablet با ویژگی‌های متحد بر پایه‌ی ویندوز ۸ و جدیدتر. افزوده شدن QGradient جدید بر پایه https://webgradients.com افزوده شدن فرمت‌های 4xU16 ،RGBA64 به QImage جهت خواندن فرمت‌های PNG و TIFF و همچنین امکان آپلود و گرفتن آن‌ها از OpenGL. ویژگی‌ها و تغییرات در QtNetwork افزوده شدن DTLS برای پشتیبانی از UDP افزوده شدن یک بازنگری مجدد برای ترنسفر ایمن در بک‌اِند. افزوده شدن پشتیبانی از ALPN در پروتکل HTTP/2 جهت امنیت ترنسفر اطلاعات. افزوده شدن پشتیبانی از ویژگی PKCS#8 در بک‌اِند عمومی (WinRT و ترنسفر اطلاعات) افزوده شدن QPasswordDigestor به عنوان یک فضای نام که شامل توابعی برای استخراج کلید بر پایه رمزعبور می‌باشد (در حال حاضر PBKDF1 و PBKDF2) در دسترس هستند. ویژگی‌ها و تغییرات در QtQml پشتیبانی از موتور نسخه‌ی ۸ جاوا اسکریپت فراهم شده است (ECMAScript 7) ماژول ECMAScript می‌تواند به طور مستقیم توسط QJSEngine::importModule() بارگذاری شود و می‌تواند فایل‌های .qml را در زمان استفاده از فایل‌های .mjs را فراهم سازد. ویژگی‌ها و تغییرات در QtQuick نوع‌های Pointer Handlers به Input Handlers تغییر نام پیدا کرده‌اند (البته ویژگی‌های مربوط به این دسته در این شاخه وجود دارند) و اکنون به طور کامل به عنوان یک ویژگی پشتیبانی شده در یک کلاس QML تحت Qt Quick پشتیبانی می‌شود. (رابط‌های برنامه‌نویسی سمت سی‌پلاس‌پلاس برای آن‌ها هنوز عمومی نشده است). نوع HoverHandler نوع جدیدی برای شناسایی ویژگی Mouse hover می باشد. این ویژگی‌ می‌تواند شناور ماوس را در موارد عمیقی شناسایی کند. بر خلاف MouseArea، شما می‌توانید چندین آیتم با HoverHandler به صورت هم‌زمان قرار دهید (برای مثال نوار کناری (SideBar) و یک دکمه‌ بر روی آن. نوع DragHandler به عنوان یک نوع چند-نقطه‌ای بشمار می‌رود. اگر شما مقدار minimumPointCount را به ۲ تغییر دهید، به کشیده شدن تنها با دو انگشت واکنش نشان خواهد داد. این ویژگی می‌تواند به مراتب آزادی‌های بیشتری را در توسعه به شما ارائه دهد. کشیده شدن توسط یک انگشت می‌تواند یک حرکت خاص را انجام دهد و کشیده شدن توسط دو انگشت می‌تواند کارهای دیگری را انجام دهد (به عنوان مثال زاویه‌ی شیب را تغییر دهد). افزوده شدن پشتیبانی از مخازن از پیش تولید شدن جهت سرعت بخشید به اجرا در زمان استارت‌آپ. افزوده شدم آیتم TableView به عنوان یک نوع دیگری از نوع Item View همانند ListView که بر خلاف آن ویژگی چند ستونه شدن را دارا می‌باشد. بر خلاف Qt Quick 1.x ویژگی ظاهری برای آن طراحی نشده است. اما جای آن فراهم شده است تا توسط delegates ها بتوانید بر اساس تقاضا آن‌ها را فراهم کنید. ویژگی DelegateChooser به عنوان پیش نمایشی از تکنولوژی ارائه شده است که به عنوان delegate های Item Views ها مانند TableView بسته به مقادیر آن‌ها کاربرد دارد. ویژگی‌ها و تغییرات در QtQuick Controls 2.x کنترل Dial ویژگی inputMode را اضافه کرده است. که دو روش جدید جهت تعامل به صورت عمودی و افقی را فراهم می‌کند. این ویژگی‌های ورودی از یک سیستم ورودی نسبی استفاده می‌کنند. به این معنی است که بر خلاف سیستم ورودی مطلق قبلی، اغییرات در موقیع شماره گیری به آن اعمال می‌شود. این ویژگی در نتیجه‌ی آن تاثیر می‌گدارد و باعث می‌شود شماره گیر پرش کمتری داشته و آن را از عملیاتی که ممکن است مضر باشد تضمین کند. کنترل Popup ویژگی‌های leftInset، bottomInset، topInset و rightInset را به بخش پس زمینه مشابه کنترل‌های paddings در contentItem اضافه کرده است. اضافه شدن خاصیت‌های implicitWidth و impliciyHeight ویژگی‌های implicitHeaderWidth و implicitContentWidth و غیره برای ساده سازی پیوند‌های اندازه‌ی ضمنی و پیچیده ارائه شده است. در کنترل‌های SwipeView و DialogButtonBox خاصیت‌های contentWidth و contentHeight افزوده شده است. در کنترل RageSlider خاصیت valueAt() به عنوان تابع اضافه شده است، که اجازه می‌دهد تا مقادیر در هر زمان از تغییر برای tooltip به‌روز و تنظیم شوند. در کنترل RangeSlider خاصیت‌های first.mode() و second.mode() به عنوان سیگنال‌هایی مشابه سیگنال moved() اضافه شده‌اند. در آیتم پایه Control، در صورتی که به صراحت مشخص شده باشد، baselineOffset به صورت خودکار فاصله‌ی بالای کنترل و baselineOffset از contentItem را کنترل می‌کند. مشخص سازی استایل برای این کنترل نیاز نیست. در کنترل Popup، خاصیت‌های anchors.centetIn به عنوان یک راه حل مناسب اجازه تنظیم مرکز یک popup را می‌دهد. آیتم QQuickStyle، افزوده شدن ویژگی‌های stylePathList() و addStylePath() به عنوان مدیریت فهرستی از سبک‌های موجود در کیوت کوئیک کنترل ۲ را فراهم می‌کند. کنترل Slider، RangeSlider ویژگی touchDragThreshold را برای پیکربندی آستانه‌ی شروع کشیدن (لمس) لغزنده فراهم می‌کند. کشیدن ماوس در این ویژگی تاثیری ندارد. در کنترل‌های TextArea و TextField خاصیت placeHolderTextColor برای راحتی کار برای افزودن رنگ در متن پیشفرض و نمایشی در پس زمینه‌ی کنترل اضافه شده است. در ویژگی Material، یک سری موارد مورد استفاده‌ی انبوه برای استفاده از این سبک در پلتفرم‌های دسکتاپ افزوده شده است.برخی از کنترل‌ها از ارتفاع و اندازه‌ی قلم کوچکتری استفاده می‌کنند. جهت پیکربندی آن نیز می‌توان از متغیر QT_QUICK_CONTROLS_MATERIAL_VARIANT جهت مشخص سازی تراکم و یا با تنظیم Variant=Dense در فایل پیکربندی qtquickcontrols2.conf استفاده کرد. کنترل DialogBoxButton خاصیت buttonLayout به آن اضافه شده است که می‌تواند برای ترتیب و مرتب ساختن دکمه‌ها از آن استفاده شود. کنترل Tumbler، تابع positionViewAtIndex() را اضافه کرده است که می‌تواند عملکرد توابع مربوط به PathView و ListView را بسته به مقدار آن‌ها بسته بندی کند. این امکان اجازه می‌دهد تا مقدار currentIndex بدون انیمیشن تغییر یابد. در Control و Popup، خاصیت‌های horizontalPadding و verticalPadding به عنوان روش مناسب جهت تنظیم جپ و راست و یا بالا و پایین فاصله‌ها در یک حرکت در نظر گرفته شده است. کنترل Tooltip، روش‌های show() و hide() را برای نمایش پارامتر‌های خاص اضافه کرده است. ویژگی‌ها و تغییرات در QtSerialBus افزوده شدن یک افزونه‌ی مجازی CAN برای شبیه سازی CAN بدون سخت‌افزار. افزوده شدن گزینه‌های پیکربندی برای canbusutil برای عنوان برای تنظیم میزان بیت‌ریت. افزوده شدن CAN FD به پلاگین PeakCAN. افزوده شدن توابع readAllFrames() و clear() به QCanBusDevice. ویژگی‌ها و تغییرات در QtWebEngine به‌روز رسانی شده به Chromium 69 رابط QWebEngineUrlScheme برای تنظیم و پیکربندی نوع و امنیت در طرح‌های سفارشی URL. ویژگی‌های WebActions در معرض QML قرار گرفته‌اند. اکنون می‌توان صفحه‌هاتی که آن‌ها را خوانده وی ا از آن‌ها دانلودی صورت گرفته است را خواند. گواهی‌نامه‌های SSL از این پس پشتیبانی می‌شوند. خواندن آن‌ها از تنظیمات macOS و Windows و بانک اطلاعاتی NSS در Linux امکانپذیر است. ویژگی‌ها و تغییرات در Qt Labs Platform در آیتم‌های Menu، MenuItem و SystemtryIcon خاصیت iconName و iconSource منسوخ شده است. در آیتم‌های Menu، MenuItem و SystemtryIcon خاصیت icon.mask افزوده شده است. ویژگی‌ها و تغییرات در Qt Virtual Keyboard یک رابط واسط برای کلید مجازی تعریف شده است. تمامی روش‌های ورودی فعلی و برخی از ویژگی‌های ویژه‌ی لایه‌های آن مانند Hunspell، OpebWnn و غیره به ویژگی‌های اضافی منتقل شده‌اند. این ویژگی اجازه می‌دهد تا ساخت و ساز‌های نوع سوم بدون دستکاری ورودی‌های پیشفرض این ماژول صورت بگیرد. با معرفی این ماژول افزونه‌های اضافی می‌توانند با آن لینک شوند. این ماژول رابط‌های برنامه‌نویسی لازم ++C را برای ایجاد یک روش ورودی جدید فراهم می‌کند. افزوده شدن گزینه‌ی build time به امکان محدود سازی تمامی سبک‌ها در پلاگین را فراهم می‌کند. پشتیبانی از MyScript برای تشخیص دست نویس اضافه شده است. ویژگی تشخیص Vietnamese در دست خط اضافه شده است. افزوده شدن لایه‌های جدید، آلبانی، آمریکایی، انگلیسی، فرانسوی، کانادایی، اندونزیایی، مالایی، پرتغال برزیبی، اسلواکی، اسلوونیایی، اسپانیایی مکزیکی، تایلندی، ترکی، ویتنامی و اکراینی. لایه‌های بیشتر در باره‌ی زبان روسی نیز اضافه شده است. برخی از لغت نامه‌ها به صورت پیش فرض تحت یک افزونه اضافه شده‌اند. فرهنک لغت کاربری Hunspell افزوده شده است. ویژگی‌ها و تغییرات در Qt Bluetooth افزوده شدن توانایی جهت کشف داده‌ها از طریف QBluetoothDeviceDiscovery ویژگی‌ها و تغییرات در Qt 3D افزوده شدن ویژگی جهت بارگیری درون یک فایل که شامل نام و شناسه‌ی مشخصی است در بخش نمایه به عنوان انیمیشن فراهم شده است. فعال شدن منحنی‌های ثابت در انیمیشن. رفع مشکلات مربتط با QNodes ها در برخی شرایط. رفع و بهبود در نمایش بافت‌ها در اشیاء نوع TextureImage دیگر به عنوان فرزند بافت در نظر گرفته نمی‌شود. زمانی که در یک حلقه‌ی شبیه سازی شده قرار گرفته نشود، استفاده از پردازنده کاهش پیدا خواهد کرد. نوع EntityLoader از این پس قادر به بارگیری از یک Component به خوبی یک فایل است. پشتیبانی از سیستم رندرینگ OpenGL ES 3.1 فراهم شده است. عملکرد‌ها و یک سری باگ‌ها در بخش بک اند رفع و کارآیی آن بهبود داده شده است. ویژگی‌ها و تغییرات در Qt Wayland Compositor افزوده شدن پشتیبانی از نسخه‌ی پایدار xdg-shell (همچنین نسخه‌ی ناپایدر ۵ آن منسوخ شده است). پشتیبانی از xdg-decoration-unstable-v1 برای سمت سرور جهت اعمال دکوراسیون پنجره‌ها اعمال شده است. ویژگی‌ها و تغییرات در Qt WebSocket تابع "bytesToWrite" به این ماژول افزوده شده است. ویژگی‌ها و تغییرات در Qt Location پلاگین MapboxGL به‌روز‌رسانی شده و پشتیبانی از QNX7 فراهم شده است. حذف خاصیت‌های add و remove و افزوده شدن آن به MapItemView آیتم MapItemView هم‌اکنون کلاس MapItemGroup را طبقه بندی می‌کند و به خودی خوب غیر قابل تغییر می‌باشد. در حال حاضر PlaceSearchModel اجازه می‌دهد تا مدل به صورت پراکنده پُر شود. ویژگی Map.visibleArea جهت محدود کردن مناطق قابل مشاهده بر روی نقشه اضافه شده است. ویژگی geoShape در آیتم‌های مربوط به MapItem به صورت R/W تنظیم شده است و یک تنظیم کننده مجازی در کلاس پایه دارد. پشتیبانی از نگه‌دارنده‌ی حفره‌ها در QGeoPolygon فراهم شده است. افزوده شدن پشتیبانی از Route Legs به پلاگین. ویژگی‌ها و تغییرات در Qt Test خطاهای مربوط به std::tuple در زمان استفاده از QCOMPARE تشخیص داده می‌شوند. ماژول‌های جدید افزوده شدن ماژول Qt Remote Objects با پشتیبانی کامل. افزوده شدن پلاگین Qt WebGL Streaming با پشتیبانی از استریم در مرورگر و اپلیکیشن‌های تحت وب. تغییرات مرتبط با پلتفرم‌ها در QTimeZone از ICU در صورتی که در دسترس باشد استفاده می‌کند (اولویت استفاده با Api‌ مایکروسافت می‌باشد). در سیستم‌عامل macOS پشتیبانی از QSurfaceType::MetalSurface فراهم شده است. در macOS پشتیبانی از QSurfaceType::VulkanSurface و QVulkanWindow از طریق MoltenVK فراهم شده است. در Wayland نسخه‌ی پایدار xdg-shell افزوده و نسخه‌ی ناپایدار ۵ آن منسوخ شده است. با استفاده از پنجره‌های پیشفرض نمایش آن‌ها زیباتر و بهتر شده است. پشتیبانی از ویژگی‌های اضافی xdg-decoration-unstable-v1 و xdg-output-unstable-v1 فراهم شده است. فناوری‌های جدید به عنوان پیش‌نمایش ویژگی Qt for WebAssembly امکان این را فراهم می‌سازد تا برنامه‌های تحت کیوت در بستر مرورگر‌ با استفاده از WebAssembly اجرا شوند. تغییرات مرتبط با Qt for Automation ویژگی Qt MQTT پشتیبانی کامل از پروتکل MQTT سطح ۵ ویژگی Qt KNX پشتیبانی از KNXnet/IP Core نسخه‌ی ۲ پشتیبانی از KNXnet/IP Routing نسخه‌ی ۱ پشتیبانی از KNXnet/IP Tunneling نسخه‌ی ۲ پشتیبانی از KNXnet/IP و برقراری ارتباط از طریق TCP پشتیبانی از KNXnet/IP Secure به صورت پیش نمایش از فناوری ویژگی Qt OPC UA پشتیبانی از Events‌ها افزوده شدن رابط‌های برنامه‌نویسی جهت خواندن به صورت دسته‌ای افزوده شدن رابط‌های برنامه‌نویسی جهت نوشتن به صورت دسته‌ای افزوده شدن یک TranslateBrowsePathsToNodeIds به رابط‌های برنامه‌نویسی رابط‌های مرورگری بهبود یافته شده پشتیبانی از انواع Argument و ExpandedNodeId نود‌ها می‌توانند از این پس از به وسیله‌ی ExpandedNodeId استفاده شوند. پشتیبانی از آرایه های چند بعدی بهبود یافته است. پشتیبانی از خواندن و نوشتن اشیاء اضافی فراهم شده است. ماژول‌های منسوخ و حذف شده ماژول Qt Script ماژول Qt Quick Controls 1 ماژول Qt Canvas 3D
  3. 1 امتیاز
    تشکر! بابت ترجمه روان و مختصر مفیدی که بابت این تغییرات جدید قرار دادید.
  4. 1 امتیاز

    نگارش 4.8.0

    36 دریافت

    محیط‌های توسعه مختلفی برای (بسته ابزار) تولکیت Qt وجود دارد که اکثراً توسط برنامه‌نویسان علاقه‌مند به‌این تولکیت ایجاد شده‌اند. جدیدترین محیط توسعه‌این تولکیت Qt Creator نام دارد. این محیط همراه با نرم‌ افزارهای دیگری برای راحتی کار با لینوکس عرضه می‌شود از جمله Assisstant که یک مجموعه از کاربردها و طرز استفاده از کتابخانه‌های کیوت، Examples and Demos که مثال‌هایی برای آشنایی هر چه بیشتر با کیوت است، زبان‌شناسی که برنامه‌ای به منظور ترجمه‌ی نرم‌افزارهای نوشته شده به‌این زبان و یا ساخت نرم‌افزارهای چند زبانه با سادگی هر چه تمام تر است و مهم تر از همه QtDesiner که نرم‌افزاری برای طراحی رابط‌های کاربری با استفاده از ویجت (دکمه، کادر متن و...) های از پیش طراحی شده است. همچنین توسط افزونه‌هایی که برای این کتابخانه نوشته شده است شما می‌توانید از محیط هایی مانند Visual Studio نیز استفاده نمایید. مهم ترین ویژگی این برنامه‌این است که برنامه‌های نوشته شده با این IDE قابلیت اجرا و پشتیبانی در طیف وسیعی از سیستم‌عامل‌ها نظیر ویندوز، لینوکس، مک و حتی تلفن های همراه نظیر سیتسم عامل سیمبین را داراست و یکی از نکات مهم این نرم افزار پشتیبانی از زبان‌های برنامه‌نویسی نظیر QML, CSS & JavaScript است. آخرین اطلاعات و مباحث مرتبط با اخبار، به‌روز‌رسانی‌ها و سوالات مرتبط با این محیط توسعه در این بخش می‌باشد. ویژگی‌های اخیر در این محیط توسعه

    رایگان

  5. 1 امتیاز
    همواره یکی از چالش بر انگیزترین مباحث در دنیای نرم افزار حفاظت از داده های حساس برنامه ها می باشد. البته امروزه با کتابخانه ها و الگوریتم های رمزنگاری موجود در این صنعت کمی از عذاب آورترین چالش های مهندسین نرم افزار کمتر شده است، ولی به هرحال تمامی این روشها جدایی از بحث انعطاف پذیری و اطمینان از صحت اجرای الگوریتم توانایی اجرا در همه سکوها را ندارند. با این مقدمه کوتاه به بحث پر چالش ترین زبان برنامه نویسی جاوا و البته سیستم عامل معروف اندروید تحت این سکو می پردازیم، همانطور که می دانید حفاظت از داده های حساس در اندروید به علت متن باز بودن سکوی خود می تواند یکی از پر چالش ترین بحث های برنامه نویسی باشد. به همین علت کتابخانه ها و روش های زیادی وجود دارند تا از این اطلاعات حساس نگهداری نمایید. البته در این مقاله بحث بر سرحفاظت از اطلاعات حساس در زمان اجرای اپ های موبایل می باشد مانند کلمات عبور و یا اطلاعات حساس استفاده شده در وب سرویس ها در زمان ارسال پکت ها به سرور می باشد. بنابراین در اینجا کاری با قسمت پایگاه داده و روش های برنامه نویسی سوکت و مباحث دیگر نخواهیم داشت. در زبان جاوای گوگل که برای سیستم عامل اندروید توسعه داده شده است ابزار قدرتمندی به نام Java Native Interface طراحی شده است که می تواند یک رابط بومی باشد برای استفاده از کیت هایی که به زبان ++C , C توسعه داده شده اند به نام Native Development Kit که با استفاده از این ابزار و برخی از ابزار های دیگر مانند ,Make ,LLDB,Clang... این امکان را خواهید داشت تا کمبود هایی که در زبان جاوا وجود دارد را با استفاده از برنامه نویسی سی و سی پلاس پلاس ، جبران نمایید. معمولا یکی از پرکاربرد ترین این برنامه ها نوشتن الگوریتم های اختصاصی رمزنگاری می باشد. به این علت که سورسهای زبان جاوا به راحتی با استفاده از تکنیک های مهندسی معکوس استخراج می شوند، به همین علت تهیه چنین الگوریتم هایی در نرم افزار های موبایل حیاتی می باشد. و البته توجه داشته باشید که می توانید از کتابخانه های آماده هم استفاده نمایید حتی سمت زبان سی پلاس پلاس ولی به هرحال اختصاصی نوشتن اینچنین الگوریتم هایی هم خالی از لطف و تجربه نخواهد بود در عین حال هم بلکه پیچیده تر از الگوریتم های آن کتابخانه باشد که بدین ترتیب روش های مهندسی معکوس را هم بسیار سخت تر خواهد کرد ویا عملا غیر ممکن خواهد شد. وبا توجه به اینکه برنامه هایی که با زبان سی و سی پلاس پلاس که نوشته می شوند مستقیم به اسمبلی تفسیر و سپس به زبان ماشین تبدیل می شوند عملا دی کامپایلر ها توانایی فهمیدن درست سورس کدها را نخواهند داشت وفقط می توانند به کد های اسمبلی که البته خیلی پیچیده تر از کد اصلی برنامه هست تبدیل نمایند. اکنون پس از این توضیحات کوتاه در زیر سورس کدهای برنامه ای درهم سازی را که از تلفیق چند روش رمزنگاری در اندروید برای استفاده سمت جاوا ی اندرید نوشته ام را خدمت شما ارسال میکنم. توضیحاتی راجع به الگوریتم ها فعلا نمیدم اگر از دوستان علاقمند بودند در همین بخش اعلام کنند تا توضیح عملکرد را خدمتتان ارائه کنم. برای استفاده باید ابزار های زیر داشته باشید JDK1.8 , JRE , Android Studio , NDK rb17 , CMAKE ,LLDB ,Android Build Tools کلاس native_utils.h #ifndef BODYPOWER_NATIVE_UTILS_H #define BODYPOWER_NATIVE_UTILS_H #include <android/log.h> #include <iomanip> #include <locale> #include <sstream> #include <memory> #define TAG_LOG_ANDROID "NativeTagLog" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG_LOG_ANDROID,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG_LOG_ANDROID,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG_LOG_ANDROID,__VA_ARGS__) using namespace std; namespace BodyPowerNative { struct Exp : public exception { const char* ExceptionDefualtMsg = "error by this exception -> %s"; public: Exp() = default; Exp(const Exp &) = default; virtual ~Exp() = default; static void destory(Exp *my) { delete my; } static unique_ptr<Exp, decltype(&destory)> instance() { return unique_ptr<Exp, decltype(&destory)>(new Exp(), &destory); } static Exp getInstance() { return Exp(); } const char* what() const noexcept override { return exception::what(); } void printStackTrace(const char *cValue) const { LOGE(ExceptionDefualtMsg, cValue); }; }; class Native_Utils { public: Native_Utils() = default; template<typename T> static string NumberToString(T Number) { ostringstream ss; ss << Number; return ss.str(); } template<typename T> static T StringToNumber(const string &Text) { istringstream ss(Text); T result; return ss >> result ? result : 0; } }; typedef Native_Utils NU; } #endif //BODYPOWER_NATIVE_UTILS_H فایل JniByteArrayWrapper.h #ifndef BODYPOWER_JNIBYTEARRAYWRAPPER_H #define BODYPOWER_JNIBYTEARRAYWRAPPER_H #include <jni.h> #include <memory> #include <algorithm> #define SHA512_BLOCK_SIZE 0x7A #define SHA512_ENDBYTE_BIGCAPS 0x5A #define SHA512_MASK 0x5B #define SHA512_STARTBYTE_CODESMALL_CAPS 0x61 #define SHA512_STARTBYTE_CODEBIG_CAPS 0x41 #define SHA512_STARTBYTECODE_NUMERIC 0x30 #define SHA512_ENDBYTE_CODE_NUMERIC 0x39 #define SHA512_START_DIGEST_BYTECODE_SMALLCAPS 0x60 #define SHA512_START_DIGEST_BYTECODE_BIGCAPS 0x40 #define SHA512_LEFT_SIDESHIFT 0xF #define SHA512_SPACE_CHARBYTE 0x1B #define PARAM_LENGTH 0xB using namespace std; namespace BodyPowerNative { class JniByteArrayWrapper { private: u_long _key = 0; u_long _sKeyLength = 0; string _stringKey; jsize _dataLength; jsize _lenHashData; jbyteArray _jb_u; JNIEnv *_jniEnv; vector<char> vectorBytes; public: JniByteArrayWrapper() = default; // default ctor JniByteArrayWrapper(JNIEnv *&, jbyteArray); //default ctor JniByteArrayWrapper(const JniByteArrayWrapper &); // copy ctor void const parseJByteArray(); virtual ~JniByteArrayWrapper(); bool operator==(const JniByteArrayWrapper &rhs) const; // equal operator overload bool operator=(const JniByteArrayWrapper &rhs) const; // assignment operator overload bool operator!=(const JniByteArrayWrapper &rhs) const; // not equal operator overload const jbyteArray getJBytes() const; const JNIEnv &getEnv() const; u_long get_key() const; u_long get_sKeyLength() const; const string &get_stringKey() const; jsize get_dataLength() const; jsize get_lenHashData() const; const vector<char> &getVectorBytes() const; void encodingNum(); }; typedef JniByteArrayWrapper jByteArrayW; } #endif //BODYPOWER_JNIBYTEARRAYWRAPPER_H فایل JniByteArrayWrapper.cpp #include "JniByteArrayWrapper.h" #include "Native_Utils.h" using namespace BodyPowerNative; JniByteArrayWrapper::JniByteArrayWrapper(const JniByteArrayWrapper &rhs) { _jb_u = rhs._jb_u; _jniEnv = rhs._jniEnv; } JniByteArrayWrapper::~JniByteArrayWrapper() { //delete[]_hash_str; vectorBytes.clear(); } bool jByteArrayW::operator=(const JniByteArrayWrapper &rhs) const { return false; } bool jByteArrayW::operator==(const JniByteArrayWrapper &rhs) const { return _jb_u == rhs._jb_u; } bool jByteArrayW::operator!=(const JniByteArrayWrapper &rhs) const { return rhs._jb_u != _jb_u; } const jbyteArray jByteArrayW::getJBytes() const { try{ jbyteArray _encryptBytes = _jniEnv->NewByteArray(_lenHashData); char *_hash_str = new char(_lenHashData); transform(vectorBytes.begin(), vectorBytes.end(), _hash_str, [&](char itByte) { return itByte; }); _jniEnv->SetByteArrayRegion(_encryptBytes, 0, _lenHashData, reinterpret_cast<const jbyte *>(_hash_str)); delete _hash_str; return _encryptBytes; } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } return 0; } const JNIEnv &jByteArrayW::getEnv() const { return *(_jniEnv); } void const jByteArrayW::parseJByteArray() { try{ unique_ptr<jbyte> _readByte = make_unique<jbyte>(); _dataLength = _jniEnv->GetArrayLength(_jb_u); for (u_int i = 0; i < _dataLength; ++i) { _jniEnv->GetByteArrayRegion(_jb_u, i, 1, _readByte.get()); vectorBytes.push_back(*(_readByte.get())); } _lenHashData = _dataLength ; } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } } void jByteArrayW::encodingNum() { try { string strKey = get_stringKey(); for (string::iterator _keyIter = strKey.begin(); _keyIter != strKey.end(); ++_keyIter) { if (*(_keyIter) >= SHA512_STARTBYTECODE_NUMERIC && *(_keyIter) <= SHA512_ENDBYTE_CODE_NUMERIC) { char shiftNum = static_cast<char>(*(_keyIter) + SHA512_LEFT_SIDESHIFT); vectorBytes.push_back(shiftNum); } } } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } } u_long jByteArrayW::get_key() const { return _key; } u_long jByteArrayW::get_sKeyLength() const { return _sKeyLength; } const string& jByteArrayW::get_stringKey() const { return _stringKey; } jsize jByteArrayW::get_dataLength() const { return _dataLength; } jsize jByteArrayW::get_lenHashData() const { return _lenHashData; } const vector<char> &JniByteArrayWrapper::getVectorBytes() const { return vectorBytes; } JniByteArrayWrapper::JniByteArrayWrapper(JNIEnv *&env, jbyteArray jb) : _jb_u(jb), _jniEnv(env) {} فایل ParseEncryptAlgol.h #ifndef BODYPOWER_PARSEENCYRPTALGOL_H #define BODYPOWER_PARSEENCYRPTALGOL_H #include <sys/types.h> namespace BodyPowerNative { class JniByteArrayWrapper; class ParseEncryptAlgol { private: u_int num_counter = 0; int _extractKeyNum = 0; int nShift = 0; char digest = 0; int *_splitKeyNumArrays; JniByteArrayWrapper*& _jniByteArrayWrapper; public: ParseEncryptAlgol(JniByteArrayWrapper*&); char evalAlgol(char byte); virtual ~ParseEncryptAlgol(); }; } #endif //BODYPOWER_PARSEENCYRPTALGOL_H فایل ParseEncryptAlgol.cpp #include "ParseEncryptAlgol.h" #include "JniByteArrayWrapper.h" using namespace BodyPowerNative ; ParseEncryptAlgol::ParseEncryptAlgol(JniByteArrayWrapper*& jniByteArrayWrapper) : _jniByteArrayWrapper(jniByteArrayWrapper) { _splitKeyNumArrays = new int[jniByteArrayWrapper->get_sKeyLength()]; } ParseEncryptAlgol::~ParseEncryptAlgol() { delete[]_splitKeyNumArrays; } char ParseEncryptAlgol::evalAlgol(char _readByte) { { if (num_counter < _jniByteArrayWrapper->get_sKeyLength()) { _extractKeyNum = _splitKeyNumArrays[num_counter++]; } else { num_counter = 0; _extractKeyNum = _splitKeyNumArrays[num_counter++]; } if (_readByte >= SHA512_STARTBYTECODE_NUMERIC && _readByte <= SHA512_ENDBYTE_CODE_NUMERIC) { return 0 ;// security::encodingNum(_readByte); } else if (_readByte + _extractKeyNum > SHA512_BLOCK_SIZE) { //z 122 nShift = _extractKeyNum > (SHA512_BLOCK_SIZE - _readByte) ? _extractKeyNum - (SHA512_BLOCK_SIZE - _readByte) : (SHA512_BLOCK_SIZE - _readByte) - _extractKeyNum; digest = static_cast<char>(SHA512_START_DIGEST_BYTECODE_SMALLCAPS + nShift); return digest; } else if (_readByte + _extractKeyNum > SHA512_ENDBYTE_BIGCAPS && _readByte <= SHA512_ENDBYTE_BIGCAPS) { //Z 90 nShift = _extractKeyNum > (SHA512_ENDBYTE_BIGCAPS - _readByte) ? _extractKeyNum - (SHA512_ENDBYTE_BIGCAPS - _readByte) : (SHA512_ENDBYTE_BIGCAPS - _readByte) - _extractKeyNum; digest = static_cast<char>(SHA512_START_DIGEST_BYTECODE_BIGCAPS + nShift); return digest; } else { return static_cast<char>(_readByte + _extractKeyNum); } } } فایل security.h #ifndef BODYPOWER_SECURITY_H #define BODYPOWER_SECURITY_H #include <jni.h> #include <string.h> #include <memory> #include "Native_Utils.h" #define Java_App_Class "com/nativeDb/materialDesign/MyApplication" namespace BodyPowerNative { class JniByteArrayWrapper; const char *BASE_URL = "--/"; const char *BODY_POWER_API_SOURCE_REF = "phpSource/"; const char *COACH_PHOTO_BASE_URL = "CoachPhoto/"; const char *SUPP_PHOTO_BASE_URL = "SuppImages/"; const char *COACH_DATA_BASE_URL = "getItems"; const char *COACH_DATA_BASE_URL_FAILD = "getItemsFaild"; const char *PROFILE_SEND_BASE_URL = "FetchProfileRow"; const char *PHOTO_PROFILE_SEND_BASE_URL = "uploadPhoto"; const char *REGISTER_USER_BASE_URL = "updateUser"; const char *EXIST_USER_BASE_URL = "checkExistUser"; const char *UPD_URL = "updateMentorList"; const char *SUPP_PROD_URL = "getItems_supp"; static u_int posSepChar =0 ; typedef unsigned int sha2_32t; typedef unsigned long sha2_64t; typedef jsize sha1_32t; typedef jbyte sha1_8; typedef struct sha512 { public: //unsigned bitMask :1; char *hash_str; char *hash_out = nullptr; inline sha512(sha1_32t lenHashData) { hash_str = new char[lenHashData]; if(!hash_str) throw Exp::getInstance(); } inline sha512(const sha512& rhs){ hash_str = new char[strlen(rhs.hash_str)]; if(!hash_str) throw Exp::getInstance(); this->hash_str = rhs.hash_str; if(hash_out != nullptr){ this->hash_out = rhs.hash_out; } } inline ~sha512() { delete[]hash_str; hash_str=nullptr; if(hash_out != nullptr) { delete[]hash_out; hash_out= nullptr; } } inline sha512& operator=(const sha512& rhs){ if(&rhs != this){ delete[]hash_str; this->hash_str = rhs.hash_str; if(hash_out != nullptr){ delete[]hash_out; this->hash_out = rhs.hash_out; } } return *this; } } sha512_ctx; class security { public: security() = default; ~security(){}; static jbyteArray encryptAlgol( JNIEnv *, jobject , jbyteArray); static jbyteArray encrypt( JNIEnv *, jobject , jbyteArray); static jbyteArray decrypt( JNIEnv *, jobject , jbyteArray); static jint customRand( JNIEnv *env, jobject , jint , jint ); static jstring baseApiUrl( JNIEnv *, jobject ); static jstring mentorApiUrl( JNIEnv *, jobject ); static jstring mentorPhotoApiUrl( JNIEnv *, jobject ); static jstring suppPhotoApiUrl( JNIEnv *, jobject ); static jstring mentorDataApiUrl( JNIEnv *, jobject ); static jstring mentorDataFaildApiUrl( JNIEnv *, jobject ); static jstring profileDataApiUrl( JNIEnv *, jobject ); static jstring profilePhotoApiUrl( JNIEnv *, jobject ); static jstring registerUserApiUrl( JNIEnv *, jobject ); static jstring privacyUserApiUrl( JNIEnv *, jobject ); static jstring updateMentorApiUrl( JNIEnv *, jobject ); static jstring suppProdApiUrl( JNIEnv *, jobject ); static jobjectArray mapParamToStringArray (JNIEnv *, jobject); static void splitKeyNum(int *&, const string&); static char encodingNum(const jbyte *); static char encodingNum(const char); private: static void encodingNum(string, char *&, jsize); static char decodingNum(const jbyte *); static string decodingNum(JNIEnv *, const jbyteArray &); static u_int getEndReadBytePos(JNIEnv *, const jbyteArray &, jsize); static void revAlgol(JNIEnv *&, _jbyteArray *, JniByteArrayWrapper *&, char *&); static void revAlgol(JNIEnv *&, _jbyteArray *, JniByteArrayWrapper *&, char *&, jbyteArray &); }; typedef security SC; static JNINativeMethod method_table[] = { {"encrypt", "([B)[B", (void *) SC::encrypt}, {"decrypt", "([B)[B", (void *) SC::decrypt}, {"customRand", "(II)I", (void *) SC::customRand}, {"baseApiUrl", "()Ljava/lang/String;", (void *) SC::baseApiUrl}, {"mentorApiUrl", "()Ljava/lang/String;", (void *) SC::mentorApiUrl}, {"mentorPhotoApiUrl", "()Ljava/lang/String;", (void *) SC::mentorPhotoApiUrl}, {"mentorDataApiUrl", "()Ljava/lang/String;", (void *) SC::mentorDataApiUrl}, {"suppPhotoApiUrl", "()Ljava/lang/String;", (void *) SC::suppPhotoApiUrl}, {"mentorDataFaildApiUrl", "()Ljava/lang/String;", (void *) SC::mentorDataFaildApiUrl}, {"profileDataApiUrl", "()Ljava/lang/String;", (void *) SC::profileDataApiUrl}, {"profilePhotoApiUrl", "()Ljava/lang/String;", (void *) SC::profilePhotoApiUrl}, {"registerUserApiUrl", "()Ljava/lang/String;", (void *) SC::registerUserApiUrl}, {"privacyUserApiUrl", "()Ljava/lang/String;", (void *) SC::privacyUserApiUrl}, {"updateMentorApiUrl", "()Ljava/lang/String;", (void *) SC::updateMentorApiUrl}, {"suppProdApiUrl", "()Ljava/lang/String;", (void *) SC::suppProdApiUrl}, {"mapParamToStringArray", "()[Ljava/lang/String;", (void *) SC::mapParamToStringArray} }; extern "C" { jint JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env; if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) { return -1; } else { jclass clazz = env->FindClass(Java_App_Class); if (clazz) { env->RegisterNatives(clazz, method_table, sizeof(method_table) / sizeof(method_table[0])); env->DeleteLocalRef(clazz); return JNI_VERSION_1_6; } else { return -1; } } } } } #endif //BODYPOWER_SECURITY_H فایل security.cpp /* const char *str = (*env)->GetStringUTFChars(env, s, 0); (*env)->ReleaseStringUTFChars(env, s, str); */ //string _jskey = static_cast<ostringstream*>( &(ostringstream() << _key) )->str(); /* uint64_t features = android_getCpuFeatures(); if ((features & ANDROID_CPU_ARM_FEATURE_NEON) == 0) { //NEON is not available } else { //NEON is available } int android_getCpuCount(void); */ #include "security.h" #include "ParseEncryptAlgol.h" #include "JniByteArrayWrapper.h" #define sum32(x) (x += *(_readByte.operator->())) #define shift_r32(_ex_num, _read_byt) nShift = (_ex_num > (SHA512_BLOCK_SIZE - _read_byt) ? \ _ex_num - (SHA512_BLOCK_SIZE - _read_byt) : \ (SHA512_BLOCK_SIZE - _read_byt) - _ex_num) #define shift_l32(_ex_num, _read_byt) nShift = (_ex_num > (SHA512_ENDBYTE_BIGCAPS - _read_byt) ? \ _ex_num - (SHA512_ENDBYTE_BIGCAPS - _read_byt) : \ (SHA512_ENDBYTE_BIGCAPS - _read_byt) - _ex_num) #define compile_num(i) ctx->hash_str[i] = encodingNum(_readByte.operator->()); #define compile_wbuf97(i) ctx->hash_str[i] = static_cast<char>(SHA512_START_DIGEST_BYTECODE_SMALLCAPS + nShift); #define compile_wbuf65(i) ctx->hash_str[i] = static_cast<char>(SHA512_START_DIGEST_BYTECODE_BIGCAPS + nShift); #define compile_wbuf(i) ctx->hash_str[i] = static_cast<char>(*(_readByte.operator->()) + _extractKeyNum); #define compile_dec_wbuf27(i) ctx->hash_str[i] = static_cast<char>(SHA512_SPACE_CHARBYTE); #define compile_dec_num(i) ctx->hash_str[i] = decodingNum(_readByte.operator->()); #define compile_dec_wbuf65(i) ctx->hash_str[i] = static_cast<char>( SHA512_MASK - \ ((*(_readByte.operator->()) - SHA512_STARTBYTE_CODEBIG_CAPS) > _extractKeyNum ? \ (*(_readByte.operator->()) - SHA512_STARTBYTE_CODEBIG_CAPS) - _extractKeyNum : \ _extractKeyNum - (*(_readByte.operator->()) - SHA512_STARTBYTE_CODEBIG_CAPS)) ); #define compile_dec_wbuf65_2(i) ctx->hash_str[i] = static_cast<char>(SHA512_BLOCK_SIZE - (_extractKeyNum - \ (*(_readByte.operator->()) - SHA512_START_DIGEST_BYTECODE_SMALLCAPS))); #define compile_dec_wbuf97(i) ctx->hash_str[i] = static_cast<char>(nlShift); #define compile_dec_wbuf(i) ctx->hash_str[i] = static_cast<char>(*(_readByte.operator->()) - _extractKeyNum); using namespace BodyPowerNative; jbyteArray security::encryptAlgol(JNIEnv *env, jobject j, jbyteArray jb) { JniByteArrayWrapper *jniByteArrayWrapper = new JniByteArrayWrapper(env, jb); jniByteArrayWrapper->parseJByteArray(); jbyteArray _encryptBytes = env->NewByteArray(jniByteArrayWrapper->get_lenHashData()); char *hash_str = new char[jniByteArrayWrapper->get_lenHashData()]; vector<char> vect = jniByteArrayWrapper->getVectorBytes(); /* ParseEncryptAlgol* parseEncryptAlgol= new ParseEncryptAlgol(jniByteArrayWrapper); transform(vect.begin(), vect.end(), hash_str,[](char byte){ return parseEncryptAlgol->evalAlgol(byte); });*/ /*security sec; int* p ; p = reinterpret_cast<int*>(&sec); char* c; c = reinterpret_cast<char*>(&sec); */ jniByteArrayWrapper->encodingNum(); env->SetByteArrayRegion(_encryptBytes, 0, jniByteArrayWrapper->get_lenHashData(), reinterpret_cast<const jbyte *>(hash_str)); delete[]hash_str; delete jniByteArrayWrapper; return _encryptBytes; } jbyteArray SC::encrypt(JNIEnv *env, jobject jclazz, jbyteArray _data) { try { auto num_counter = 0; auto _extractKeyNum = 0; auto nShift = 0; sha2_64t _key = 0; sha1_32t _dataLength = env->GetArrayLength(_data); if (_dataLength == 0) throw Exp::getInstance(); unique_ptr<sha1_8> _readByte = make_unique<sha1_8>(); if(!_readByte) throw Exp::getInstance(); for (sha2_32t i = 0; i < _dataLength; ++i) { env->GetByteArrayRegion(_data, i, 1, _readByte.get()); sum32(_key); } string _stringKey = NU::NumberToString(_key); sha2_64t _sKeyLength = _stringKey.length(); int *_splitKeyNumArrays{new int[_sKeyLength]}; if(_splitKeyNumArrays == nullptr) throw Exp::getInstance(); sha1_32t lenHashData = _dataLength + static_cast<int>(_sKeyLength); sha512_ctx *ctx = new sha512_ctx(lenHashData); jbyteArray _encryptBytes = env->NewByteArray(lenHashData); splitKeyNum(_splitKeyNumArrays, _stringKey); for (sha2_32t i = 0; i < _dataLength; ++i) { if (num_counter >= _sKeyLength) { num_counter = 0; } _extractKeyNum = _splitKeyNumArrays[num_counter++]; env->GetByteArrayRegion(_data, i, 1, _readByte.operator->()); jbyte jbRead = *(_readByte.operator->()); if (jbRead >= SHA512_STARTBYTECODE_NUMERIC && jbRead <= SHA512_ENDBYTE_CODE_NUMERIC) { compile_num(i); } else if (jbRead + _extractKeyNum > SHA512_BLOCK_SIZE) { //z 122 shift_r32(_extractKeyNum, jbRead); compile_wbuf97(i); } else if (jbRead + _extractKeyNum > SHA512_ENDBYTE_BIGCAPS && jbRead <= SHA512_ENDBYTE_BIGCAPS) { //Z 90 shift_l32(_extractKeyNum, jbRead); compile_wbuf65(i); } else { compile_wbuf(i); } } encodingNum(NU::NumberToString(_key), ctx->hash_str, _dataLength); { env->SetByteArrayRegion(_encryptBytes, 0, lenHashData, reinterpret_cast<const jbyte *>(ctx->hash_str)); JniByteArrayWrapper *jniByteArrayWrapper; revAlgol(env, _encryptBytes, jniByteArrayWrapper, ctx->hash_out); env->SetByteArrayRegion(_encryptBytes, 0, jniByteArrayWrapper->get_lenHashData(), reinterpret_cast<const jbyte *>(ctx->hash_out)); delete jniByteArrayWrapper; jniByteArrayWrapper = nullptr; } _readByte.reset(); // delete smart pointer //delete _readByte.operator->(); delete[]_splitKeyNumArrays; delete ctx; env->DeleteLocalRef(_data); _splitKeyNumArrays = nullptr; return _encryptBytes; } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } return nullptr; } void SC::revAlgol(JNIEnv *&env, _jbyteArray *_encryptBytes, JniByteArrayWrapper *&jbw, char *&hash_out) { jbw = new JniByteArrayWrapper(env, _encryptBytes); jbw->parseJByteArray(); hash_out = new char[jbw->get_lenHashData()]; vector<char> vect = jbw->getVectorBytes(); transform(vect.rbegin(), vect.rend(), hash_out, [&](char byte) { //__android_log_print(ANDROID_LOG_ERROR,TAG_LOG_ANDROID,"this lambda -> %lu" ,jbw->get_key()); return byte; }); } void SC::revAlgol(JNIEnv *&env, _jbyteArray *_encryptBytes, JniByteArrayWrapper *&jbw, char *&hash_str, jbyteArray &_encryptBytes_dest) { revAlgol(env, _encryptBytes, jbw, hash_str); _encryptBytes_dest = env->NewByteArray(jbw->get_lenHashData()); env->SetByteArrayRegion(_encryptBytes_dest, 0, jbw->get_lenHashData(), reinterpret_cast<const jbyte *>(hash_str)); } char SC::encodingNum(const jbyte * _keyIter) { char shiftNum; try { shiftNum = static_cast<char>(*(_keyIter) - SHA512_LEFT_SIDESHIFT); } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } return shiftNum; } char SC::encodingNum(const char byte) { char shiftNum; try { shiftNum = static_cast<char>(byte - SHA512_LEFT_SIDESHIFT); } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } return shiftNum; } char SC::decodingNum(const jbyte *_keyIter) { char shiftNum; try { shiftNum = static_cast<char>(*(_keyIter) + SHA512_LEFT_SIDESHIFT); } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } return shiftNum; } void SC::encodingNum(string strNum, char *&hash_str, jsize len) { try { for (string::iterator _keyIter = strNum.begin(); _keyIter != strNum.end(); ++_keyIter) { if (*(_keyIter) >= SHA512_STARTBYTECODE_NUMERIC && *(_keyIter) <= SHA512_ENDBYTE_CODE_NUMERIC) { char shiftNum = static_cast<char>(*(_keyIter) - SHA512_LEFT_SIDESHIFT); hash_str[len++] = shiftNum; } } } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } } string security::decodingNum(JNIEnv *env, const jbyteArray &_data) { try { jsize _dataLength = env->GetArrayLength(_data); unique_ptr<jbyte> _readByte = make_unique<jbyte>(); if(!_readByte) throw Exp::getInstance(); string shiftNum; char numChar; //sum all bytes. posSepChar = getEndReadBytePos(env, _data, _dataLength); for (u_int _k = _dataLength - posSepChar; _k < _dataLength; ++_k) { env->GetByteArrayRegion(_data, _k, 1, _readByte.operator->()); if (*(_readByte.operator->()) >= (SHA512_STARTBYTECODE_NUMERIC - SHA512_LEFT_SIDESHIFT) && *(_readByte.operator->()) <= (SHA512_ENDBYTE_CODE_NUMERIC - SHA512_LEFT_SIDESHIFT)) { numChar = static_cast<char>(*(_readByte.operator->()) + SHA512_LEFT_SIDESHIFT); shiftNum += numChar; } } _readByte.release(); delete _readByte.operator->(); return shiftNum; } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } return nullptr; } u_int SC::getEndReadBytePos(JNIEnv *env, const jbyteArray &_data, jsize _dataLength) { sha2_64t _key = 0; unique_ptr<jbyte> _readByte = make_unique<jbyte>(); if(!_readByte) throw Exp::getInstance(); for (u_int i = 0; i < _dataLength; ++i) { env->GetByteArrayRegion(_data, i, 1, _readByte.operator->()); sum32(_key); } _readByte.reset(); // delete smart pointer //delete _readByte.operator->(); return static_cast<u_int>(NU::NumberToString(_key).length()); } jbyteArray SC::decrypt(JNIEnv *env, jobject jclazz, jbyteArray _encryptData) { try { jbyteArray _encryptBytes2; { JniByteArrayWrapper *jniByteArrayWrapper; char *hash_in; revAlgol(env, _encryptData, jniByteArrayWrapper, hash_in, _encryptBytes2); delete[]hash_in; hash_in= nullptr; delete jniByteArrayWrapper; jniByteArrayWrapper= nullptr; } string _stringKey = decodingNum(env, _encryptBytes2); auto num_counter = 0; auto _extractKeyNum = 0; unique_ptr<jbyte> _readByte = make_unique<jbyte>(); if(!_readByte) throw Exp::getInstance(); jsize _dataLength = env->GetArrayLength(_encryptBytes2); if (_dataLength == 0) throw Exp::instance(); auto _orginalSizeOfHashArrays = _dataLength - posSepChar; sha512_ctx *ctx = new sha512_ctx(_orginalSizeOfHashArrays); jbyteArray _encryptBytes = env->NewByteArray(_orginalSizeOfHashArrays); auto _keyLen = _stringKey.length(); int *_splitKeyNumArrays = new int[_keyLen]; splitKeyNum(_splitKeyNumArrays, _stringKey); for (u_int i = 0; i < _dataLength - posSepChar; ++i) { if (i >= _dataLength - posSepChar) { compile_dec_wbuf27(i); } else { if (num_counter < _keyLen) { _extractKeyNum = _splitKeyNumArrays[num_counter++]; } else { num_counter = 0; _extractKeyNum = _splitKeyNumArrays[num_counter++]; } env->GetByteArrayRegion(_encryptBytes2, i, 1, _readByte.operator->()); jbyte jbRead = *(_readByte.operator->()); if (jbRead >= (SHA512_STARTBYTECODE_NUMERIC - SHA512_LEFT_SIDESHIFT) && jbRead <= (SHA512_ENDBYTE_CODE_NUMERIC - SHA512_LEFT_SIDESHIFT)) { compile_dec_num(i); } else if (jbRead < SHA512_MASK && jbRead - _extractKeyNum <= SHA512_ENDBYTE_BIGCAPS) { auto nlShift = jbRead - _extractKeyNum; if (nlShift <= SHA512_START_DIGEST_BYTECODE_BIGCAPS) { compile_dec_wbuf65(i); } else { compile_dec_wbuf97(i); } } else if (*(_readByte.get()) - _extractKeyNum < SHA512_STARTBYTE_CODESMALL_CAPS) { compile_dec_wbuf65_2(i); } else { compile_dec_wbuf(i); } } } env->SetByteArrayRegion(_encryptBytes, 0, _orginalSizeOfHashArrays, reinterpret_cast<const jbyte *>(ctx->hash_str)); _readByte.release(); delete _readByte.operator->(); delete[]_splitKeyNumArrays; delete ctx; env->DeleteLocalRef(_encryptBytes2); env->DeleteLocalRef(_encryptData); _splitKeyNumArrays= nullptr; return _encryptBytes; } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } return nullptr; } void SC::splitKeyNum(int *&_splitKeyNumArrays, const string &_stringKey) { try { auto _sCounter = 0; string str_num ; for(auto const _key : _stringKey){ str_num = NU::NumberToString(_key); *(_splitKeyNumArrays+_sCounter++) = NU::StringToNumber<int>(str_num); } } catch (exception &E) { static_cast<Exp &>(E).printStackTrace(E.what()); } } jint SC::customRand(JNIEnv *env, jobject jclazz, jint total, jint total_draw) { /* if (total < total_draw) return 0; srand(static_cast<u_int>(time(NULL))); // create the seeds u_int *balls = new u_int[static_cast<u_int>(total_draw)]; // create new array for (u_int i = 0; i < total_draw; i++) { balls[i] = static_cast<u_int>(rand()) + total + 1; // genrate the rand number for (u_int j = 0; j < i + 1; j++) { if (balls[i] == balls[j] && i != j) { // if duplicate rand number forward and recreate rand i--; break; } else if (j == i) { // if rand number is that uniqe. return reinterpret_cast<jint>(env->NewIntArray(balls[i])); } } } delete[] balls;*/ return 0; } jstring SC::baseApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(BASE_URL); } jstring SC::mentorApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(BODY_POWER_API_SOURCE_REF); } jstring SC::mentorPhotoApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(COACH_PHOTO_BASE_URL); } jstring SC::mentorDataApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(COACH_DATA_BASE_URL); } jstring SC::mentorDataFaildApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(COACH_DATA_BASE_URL_FAILD); } jstring SC::suppPhotoApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(SUPP_PHOTO_BASE_URL); } jstring SC::profileDataApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(PROFILE_SEND_BASE_URL); } jstring SC::profilePhotoApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(PHOTO_PROFILE_SEND_BASE_URL); } jstring SC::registerUserApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(REGISTER_USER_BASE_URL); } jstring SC::privacyUserApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(EXIST_USER_BASE_URL); } jstring SC::updateMentorApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(UPD_URL); } jstring SC::suppProdApiUrl(JNIEnv *env, jobject jclazz) { return env->NewStringUTF(SUPP_PROD_URL); } jobjectArray SC::mapParamToStringArray(JNIEnv *env, jobject jclazz) { char *message[PARAM_LENGTH] = {const_cast<char *>("type"), const_cast<char *>("action"), const_cast<char *>("user"), const_cast<char *>("pass"), const_cast<char *>("group"), const_cast<char *>("netid"), const_cast<char *>("consumer"), const_cast<char *>("timestam"), const_cast<char *>("agent"), const_cast<char *>("login"), const_cast<char *>("profile")}; jobjectArray ret = env->NewObjectArray(PARAM_LENGTH, env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int ic_ = 0; ic_ < PARAM_LENGTH; ic_++) { env->SetObjectArrayElement( ret, ic_, env->NewStringUTF(message[ic_])); } return ret; } و برای استفاده هم در سمت اندورید هم به روش های زیر انجام دهید. static { System.loadLibrary("native-lib"); } public static native byte[] encrypt(byte[] bytes); public static native byte[] decrypt(byte[] bytes); public static native int customRand(int total,int totalDraw); public static native String baseApiUrl(); public static native String mentorApiUrl(); public static native String mentorPhotoApiUrl(); public static native String suppPhotoApiUrl(); public static native String mentorDataApiUrl(); public static native String mentorDataFaildApiUrl(); public static native String profileDataApiUrl(); public static native String profilePhotoApiUrl(); public static native String registerUserApiUrl(); public static native String privacyUserApiUrl(); public static native String updateMentorApiUrl(); public static native String suppProdApiUrl(); public static native String[] mapParamToStringArray(); public interface ApiPropertiesService { @Native String BASE_URL = baseApiUrl(); @Native String BODY_API_URL = BASE_URL + mentorApiUrl(); @Native String MENTOR_PHOTO_BASE_URL = BASE_URL + mentorPhotoApiUrl(); @Native String SUPP_PHOTO_BASE_URL = BASE_URL + suppPhotoApiUrl(); @Native String COACH_DATA_BASE_URL = BODY_API_URL + mentorDataApiUrl() ; @Native String COACH_DATA_BASE_URL_FAILD = BODY_API_URL + mentorDataFaildApiUrl() ; @Native String PROFILE_SEND_BASE_URL = BODY_API_URL + profileDataApiUrl() ; @Native String PHOTO_PROFILE_SEND_BASE_URL = BODY_API_URL + profilePhotoApiUrl(); @Native String REGISTER_USER_BASE_URL = BODY_API_URL + registerUserApiUrl(); @Native String EXIST_USER_BASE_URL = BODY_API_URL + privacyUserApiUrl(); @Native String UPD_URL = BODY_API_URL + updateMentorApiUrl(); @Native String SUPP_URL = BODY_API_URL + suppProdApiUrl(); @Native String[] MAP_PARAM = mapParamToStringArray(); } String pass = "abcd"; encryption(pass.toByte()); private String encryption(byte[] jByte) { try { if (jByte != null && jByte.length > 0) { byte[] enc = encrypt(jByte); StringBuilder byteToStr = new StringBuilder(); for (byte readByte : enc) { byteToStr.append((char) readByte); } return byteToStr.toString(); } } catch (Exception e) { e.printStackTrace(); } return ""; } private String decryption(byte[] encryptedBytes) { try { if (encryptedBytes != null && encryptedBytes.length > 0) { byte[] dec = decrypt(encryptedBytes); StringBuilder byteToStr = new StringBuilder(); for (byte chars : dec) { if (chars != 27) byteToStr.append((char) chars); } Log.i("NativeTagLog", "dec with c++ : " + byteToStr.toString() + " and len dec data : " + byteToStr.length()); return byteToStr.toString(); } } catch (Exception e) { e.printStackTrace(); } return ""; }
  6. 1 امتیاز
    بهتره که سورس کد تون را اینجا قرار می دادید! ولی یک مثال میزنم... در مثال زیر دوتا نخ داریم یک نخ اصلی و یک نخ کارگر ، بعد از شروع نخ کارگر یک سیگنال را از توی نخ اصلی ارسال میکنیم و نخ کارگر را به حالت انتظار می بریم اگر یکبار کدزیر را اجراکنید بهتر متوجه میشید. پس نکته قابل ذکر این هست که شما باید نخ کارگر را با استفاده از این متد b.moveToThread(&wThread); به حوضچه نخ های QObject ارسال کنید اگر می خواهید از چند نخ استفاده کنید در کنار نخ اصلی برنامه. البته معمولا استفاده از کتابخانه های همزمانی مانند QtConcurrent خیلی بهینه تر مدیریت نخ ها را برای شما انجام می دهند.! #include <QtCore> struct myThread : QObject { Q_OBJECT Q_SLOT void aSlot() { qDebug() << QThread::currentThread(); QThread::currentThread()->quit(); } Q_SIGNAL void aSignal(); }; int main(int argc, char ** argv) { QCoreApplication app{argc, argv}; //set the name for main thread QThread::currentThread()->setObjectName("main"); //create new worker thread QThread wThread; wThread.setObjectName("worker_thread"); myThread a, b; b.moveToThread(&wThread);//move worker thread to QObject pool thread wThread.start(); QObject::connect(&a, &myThread::aSignal, &b, &myThread::aSlot); emit a.aSignal(); // the signal is emitted from the main thread wThread.wait(); }
این صفحه از پرچمداران بر اساس منطقه زمانی تهران/GMT+03:30 می باشد
×