Тема: На розпутті вибору мови програмування

Порадьте мову програмування. Зараз для свого великого проекту я використовую JS (NODE/V8) і воно більш-менш задовольняє мої вимоги, але є декілька проблем - не компілюється у виконувані файли, робота з нейтів кодом робиться через сраку, все занадто багатопоточне (наприклад немає навіть вбудованої функції execSync, яка б запускала файл і очікувала ), для мого фаху майже нема бібліотек тому доводиться їх писати самостійно, не напишеш графічну оболонку, людський синтаксис і функціонал забезпечується сторонніми бібліотеками, які знов-таки доводиться редагувати, бо вбудовані функції не можливо замінити. Я бачив проект AppJS та подібні проекти, де Node JS собачать до браузера, обфускують JS код, запаковують це все разом і називають це "компіляцією". Звичайно, це крок вперед у прорівнянні з Visual Basic/QBasic компілерами, які в кінець інтерпретатора додавали джерельний код програми, але мені не підходить.

З иншого боку JS підтримує ООП, функціональщину, метапрограмування (хоча зараз я не використовую, але мені воно сподобалося) і звичайну інфіксну форму запису виразів. Отож порадьте мову програмування, яка б задовільнила мої потреби. Зараз я приглядаюся до пайтона, скали, рубі, перла та луа. Поки рубі перемагає, хоча занадто суворе ООП мене відлякує, проте ґламурне відео манить. Скала також подобається, але більше через спільноту білих людей. Плюси не пропонувати, бо одоробло. Якщо б воно не було одороблом - перейшов би давно на них, як на одну з головних мов розробки. Препроцесор мого улюбленого асемблера FASM підтримує вже років десять як такі маніпуляції з даними, які жадним с++ препроцесорам і не снилися (принаймні до с++11) - наприклад шифрування даних в RC4 або XTEA (звичайно, що це не вбудована можливість, але препроцесор дає змогу писати такі макроси). Мені хіба що функцій роботи з файлами в препроцесорі фасма не вистачає і отримання випадкових чисел, але відсутність останньої можливості - політика партії ідеологія фасма.

Трошки дровішок до фасм/С++ холівару:
В 2011 році якісь хацькери зламали крипт-сервіс і виклали все це добро на світ божий. Шматки коду наочно показують до якої індусії треба прибігати, щоб змусити компілер всього-навсього поксорити рядок і простенький геш порахувати.

#define A 'A' ^ XorByte 
#define B 'B' ^ XorByte 
#define C 'C' ^ XorByte 
...
#define X 'X' ^ XorByte 
#define Y 'Y' ^ XorByte 
#define Z 'Z' ^ XorByte 

І те саме для малих літер.
Використання цих "макросів" наведено нижче. І це лише простецький ксор!

TextFromXORText(GetLastError, 12, G, _e, _t, L, _a, _s, _t, E, _r, _r, _o, _r);

А ось це - отримання 32-бітних значень гешів. Тут вже кодер зрозумів, що на плюсах мертві бджоли не загудуть і зробив на PHP:

function phash($str, $xorByte)
{
    $h = 0x1337;
    for($p = 0; $p < strlen($str); $p++){
        $h = ($xorByte * $h + ord(substr($str, $p, 1)) & 0xFFFFFFFF);
    }
    return dechex($h); 
}

function GetFunctionHashDefines($xorByte){

$GetLastError = phash("GetLastError", $xorByte);
$DialogBoxParamA = phash("DialogBoxParamA", $xorByte);
$GetModuleFileNameExA = phash("GetModuleFileNameExA", $xorByte);
$GetModuleFileNameA = phash("GetModuleFileNameA", $xorByte);
$CreateProcessA = phash("CreateProcessA", $xorByte);
$GetStartupInfoA = phash("GetStartupInfoA", $xorByte);
$RtlMoveMemory = phash("RtlMoveMemory", $xorByte);
$VirtualAllocEx = phash("VirtualAllocEx", $xorByte);
$FindResourceA = phash("FindResourceA", $xorByte);
$LoadResource = phash("LoadResource", $xorByte);
$LockResource = phash("LockResource", $xorByte);
$NtUnmapViewOfSection = phash("NtUnmapViewOfSection", $xorByte);
$NtContextGetThread = phash("NtContextGetThread", $xorByte);
$NtContextSetThread = phash("NtContextSetThread", $xorByte);
$NtResumeThread = phash("NtResumeThread", $xorByte);
$WriteProcessMemory = phash("WriteProcessMemory", $xorByte);
$GetThreadContext = phash("GetThreadContext", $xorByte);
$SetThreadContext = phash("SetThreadContext", $xorByte);
$ResumeThread = phash("ResumeThread", $xorByte);
$NtWriteVirtualMemory = phash("NtWriteVirtualMemory", $xorByte);

$config_data = <<<CONF

#define HashGetLastError 0x$GetLastError
#define HashDialogBoxParamA 0x$DialogBoxParamA
#define HashGetModuleFileNameExA 0x$GetModuleFileNameExA
#define HashGetModuleFileNameA 0x$GetModuleFileNameA
#define HashCreateProcessA 0x$CreateProcessA
#define HashGetStartupInfoA 0x$GetStartupInfoA
#define HashRtlMoveMemory 0x$RtlMoveMemory
#define HashVirtualAllocEx 0x$VirtualAllocEx
#define HashFindResourceA 0x$FindResourceA
#define HashLoadResource 0x$LoadResource
#define HashLockResource 0x$LockResource
#define HashNtUnmapViewOfSection 0x$NtUnmapViewOfSection
#define HashNtContextGetThread 0x$NtContextGetThread
#define HashNtContextSetThread 0x$NtContextSetThread
#define HashNtResumeThread 0x$NtResumeThread
#define HashWriteProcessMemory 0x$WriteProcessMemory
#define HashGetThreadContext 0x$GetThreadContext
#define HashSetThreadContext 0x$SetThreadContext
#define HashResumeThread 0x$ResumeThread
#define HashNtWriteVirtualMemory 0x$NtWriteVirtualMemory

CONF;

return $config_data;

}

І мій макрос для отримання гешу (трошки инший алгоритм) з рядка:

macro GETHASH res, name {
  local ..size, ..result, ..temp
  ..result = 0
  ..temp = 0
  virtual at 0
    db name, 0
    ..size = $
      repeat ..size
        load ..char byte from % - 1 ; зчитування 
        ..temp = (..temp shr 7) or (..temp shl 25) ; циклічний зсув вправо на 7 біт 32-бітного операнда
        ..result = ..result xor ..temp
        ..temp = (..temp and 0xffffff00) or ..char
      end repeat
    res = ..result and 0xffffffff
  end virtual
}

Натомість я, використовуючи цей макрос, можу написати:

GETHASH hashMessageBoxA, 'MessageBoxA'

hashMessageBoxA міститиме значення гешу з рядкового ASCII значення MessageBoxA, до якого в кінці додається нульовий байт. Зовсім нескладно написати макрос, який повністю автоматизує отримання значень гешів, тобто щось наподобі цього (переробимо попередній шматок PHP файлу для нашого нового макросу Hashes):

Hashes GetLastError, DialogBox, GetModuleFileNameExA, GetModuleFileNameA, CreateProcessA, GetStartupInfoA, RtlMoveMemory, VirtualAllocEx, \
VirtualAllocEx, FindResourceA, LoadResource, LockResource, NtUnmapViewOfSection, NtContextGetThread, NtContextSetThread, NtResumeThread, \
WriteProcessMemory, GetThreadContext, SetThreadContext, ResumeThread, NtWriteVirtualMemory

І напишемо тепер макрос Hashes, який значно полегшить роботу.

macro Hashes [hzv] {
  forward GETHASH hash#hzv, `hzv
}

Як бачимо, його довжина складає лише 3 рядки. Таким чином робимо висновок, що фасм завдяки препроцесору і лінкеру (точніше його відсутності :D) більш високорівнева мова за плюси, бо забезпечує кращу абстракцію даних. І це ще далеко не "чорна магія", а очевидні можливості фасма.
Ану виходьте сішні одепти будемо препроцесорами і лінкерами міряться :p До речі, плюси я люблю як стадію розвитку програмерської думки і за гарних ґиків-одептів -Страуструпа, Шилдта і Деніса Рітчі (нехай спочива його дух у Вальгалі).

Як бачите, я використовую для своїх поточних проектів фасм+джаваскрипт, але яка тому альтернатива?

LET'S HOLY WAR BEGIN!

2

Re: На розпутті вибору мови програмування

Python та C++ вкупі. На Пітоні зручно й швидко писАти, а хрести - для швидкотребних операцій. Можна використати Cython, як варіант.