Форум программистов, компьютерный форум, киберфорум
Криптография
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 10.06.2019
Сообщений: 7

Не получается понять алгоритм биткоина при понятном SHA256

18.04.2021, 12:43. Показов 1197. Ответов 1

Студворк — интернет-сервис помощи студентам
Доброго всем.
Я начинающий С++. Первый проект (рабочий) - реализовал функцию SHA256 для сообщений до 441 бита.
Теперь пытаюсь победить алгоритм биткоина. И вот тут затык... похоже, не понимаю сам алгоритм.

// Как делаю:
Имеем на входе сообщение из 80 символов.
Делаю хеш первых 64 символов (512 бит) - получаю 256-битное "Х".
Беру следующие 16 символов (128 бит), добавляю "1", вписываю размер всего сообщения - хеширую - получаю 256-битное "Y".
Делаю конкатенацию X и Y и вычисляю его хеш... и вот тут не понимаю - а куда мне вписать "1" и длину сообщения? У меня УЖЕ 512 бит, т.е. полностью заполненный блок для SHA256.


Источник моего вдохновения не дает ответа на мой вопрос, но на всякий я запустил указанный на этой странице скрипт на PHP - все заработало.

На всякий, в спойлере мои С++ каракули
это сам проект,
Кликните здесь для просмотра всего текста

#include <bitset>
#include <iostream>
#include <charconv>

#include "const_sha256.h" //константы АНБ
/*
char version[9] = "02000000"; // Block 125552 без инверсии байтов
char prev_block[65] = "17975b97c18ed1f7e255adf297599b55330edab 87803c8170100000000000000";
char merkle_root[65] = "8a97295a2747b4f1a0b3948df3990344c0e19fa 6b2b92b3a19c8e6badc141787";
char timestamp[9] = "358b0553";
char bits[9] = "535f0119";
char nonce[9] = "48750833";
*/

char version[9] = "00000002"; //конвертированное значение, Block 125552
char prev_block[65] = "000000000000000117c80378b8da0e33559b599 7f2ad55e2f7d18ec1975b9717";
char merkle_root[65] = "871714dcbae6c8193a2bb9b2a69fe1c0440399f 38d94b3a0f1b447275a29978a";
char timestamp[9] = "53058b35";
char bits[9] = "19015f53";
char nonce[9] = "33087548";

uint32_t mess[20]; // первые 16 - первый блок, следующие 4 - второй
uint32_t w[64];

int i = 0, z = 0;

uint32_t s0 = 0, s1 = 0; //переменные необходимые для преобразований
uint32_t a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
uint32_t ch = 0, maj = 0, temp1 = 0, temp2 = 0;

uint32_t hh[8]; //для временного хранения наших хешей в циклах хеширования


void func_sha256()
{
for (i = 0; i < 16; i++)
{
std::cout << "\n w[" << std::dec << i << "]= " << std::hex << w[i] << " = " << std::bitset<32>(w[i]);
}

//Теперь начинаем цикл хеширования, в цикле составляем 48 слов (s[i]), с 16-го по 63-е
for (i = 16; i < 64; i++)
{
s0 = (((w[i - 15] >> 7) | (w[i - 15] << (32 - 7))) //rightrotate 7 for s0
^ ((w[i - 15] >> 18) | (w[i - 15] << (32 - 18))) //rightrotate 18 for s0
^ (w[i - 15] >> 3)); // XOR for s0 //rightshift 3 for s0

s1 = (((w[i - 2] >> 17) | (w[i - 2] << (32 - 17))) //rightrotate 17 for s1
^ ((w[i - 2] >> 19) | (w[i - 2] << (32 - 19))) //rightrotate 19 for s1
^ (w[i - 2] >> 10)); // XOR for s1 //rightshift 10 for s1

w[i] = w[i - 16] + s0 + w[i - 7] + s1;
}


a = h0; // цикл сжатия
b = h1; //Установим первоначальные значения равными константам АНБ
c = h2;
d = h3;
e = h4;
f = h5;
g = h6;
h = h7;

for (i = 0; i < 64; i++)
{
s1 = (((e >> 6) | (e << (32 - 6))) //rightrotate 6 for e
^ ((e >> 11) | (e << (32 - 11))) //rightrotate 11 for e
^ ((e >> 25) | (e << (32 - 25)))); // XOR //rightrotate 25 for e
ch = (e & f) | (~e & g); // (e and f) xor ((not e) and g)
temp1 = h + s1 + ch + k[i] + w[i];


s0 = (((a >> 2) | (a << (32 - 2))) //rightrotate 2 for a
^ ((a >> 13) | (a << (32 - 13))) //rightrotate 13 for a
^ ((a >> 22) | (a << (32 - 22)))); // XOR //rightrotate 22 for a
maj = (a & b) | (a & c) | (b & c); // (a and b) xor (a and c) xor (b and c)
temp2 = s0 + maj;

h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}

//std::cout << "\n\n ___h0___ = " << std::hex << h0;

hh[0] = h0 + a;
hh[1] = h1 + b;
hh[2] = h2 + c;
hh[3] = h3 + d;
hh[4] = h4 + e;
hh[5] = h5 + f;
hh[6] = h6 + g;
hh[7] = h7 + h;

//std::cout << "\n ___a = " << std::hex << a;
//std::cout << "\n _hh[0]_res = " << std::hex << hh[0];

}



int main()
{

std::from_chars(version, version + 8, mess[0], 16); // mess[0] = version

std::from_chars(prev_block, prev_block + 8, mess[1], 16); // mess[1..8] = prev_block
std::from_chars(prev_block + 8, prev_block + 16, mess[2], 16);
std::from_chars(prev_block + 16, prev_block + 24, mess[3], 16);
std::from_chars(prev_block + 24, prev_block + 32, mess[4], 16);
std::from_chars(prev_block + 32, prev_block + 40, mess[5], 16);
std::from_chars(prev_block + 40, prev_block + 48, mess[6], 16);
std::from_chars(prev_block + 48, prev_block + 56, mess[7], 16);
std::from_chars(prev_block + 56, prev_block + 64, mess[8], 16);

std::from_chars(merkle_root, merkle_root + 8, mess[9], 16); // mess[9..16] = merkle_root
std::from_chars(merkle_root + 8, merkle_root + 16, mess[10], 16);
std::from_chars(merkle_root + 16, merkle_root + 24, mess[11], 16);
std::from_chars(merkle_root + 24, merkle_root + 32, mess[12], 16);
std::from_chars(merkle_root + 32, merkle_root + 40, mess[13], 16);
std::from_chars(merkle_root + 40, merkle_root + 48, mess[14], 16);
std::from_chars(merkle_root + 48, merkle_root + 56, mess[15], 16);
std::from_chars(merkle_root + 56, merkle_root + 64, mess[16], 16);

std::from_chars(timestamp, timestamp + 8, mess[17], 16); // mess[17] = timestamp

std::from_chars(bits, bits + 8, mess[18], 16); // mess[18] = bits (сложность)

std::from_chars(nonce, nonce + 8, mess[19], 16); // mess[19] = nonce




std::cout << "\n " << std::hex << mess[0];
std::cout << "\n " << std::hex << mess[1] << mess[2] << mess[3] << mess[4] <<
mess[5] << mess[6] << mess[7] << mess[8];
std::cout << "\n " << std::hex << mess[9] << mess[10] << mess[11] << mess[12] <<
mess[13] << mess[14] << mess[15] << mess[16];
std::cout << "\n " << std::hex << mess[17];
std::cout << "\n " << std::hex << mess[18];
std::cout << "\n " << std::hex << mess[19];
std::cout << "\n\n";




// 1. хеш первой части сообщения (midstate)

for (z = 0; z < 16; z++) // значение сообщения, которое преобразовываем
{
w[z] = mess[z];
}


std::cout << "\n";
for (z = 0; z < 16; z++) // смотрим значение 1 сообщения, которое преобразовываем
{
std::cout << w[z];
}
std::cout << " - 1 message\n";



func_sha256();

std::cout << "\n\n hash1 = " << std::hex << hh[0] << std::hex << hh[1] << std::hex << hh[2] <<
std::hex << hh[3] << std::hex << hh[4] << std::hex << hh[5] << std::hex << hh[6] <<
std::hex << hh[7] << "\n\n";

uint32_t w_temp[16]; // записываем значения во временную переменную с 0 по 7
for (z = 0; z < 8; z++)
{
w_temp[z] = hh[z];
}



// 2. хеш второй части сообщения

for (z = 0; z < 4; z++)
{
w[z] = mess[z + 16]; // первые 4ре значения значение 2 сообщения
}

for (z = 4; z < 16; z++)
{
w[z] = 0;
}

w[4] = 2147483648; //добавляем последним значением массива '1_с 31 нулем'
// так как нужно добавить последним 1 БИТ, поэтому 1000 0000 а не 0000 0001

// записываем длину сообщения в 34-е и 35 слово как 0000 0010 и 1000 0000 (640 бит в dec)
w[15] = 0b1010000000; // (16 + 4) * 32, это 20 слов по 32 бита

std::cout << "\n";
for (z = 0; z < 16; z++) // смотрим значение 2 сообщения, которое преобразовываем
{
std::cout << w[z];
}
std::cout << " - 2 message\n";

func_sha256();

std::cout << "\n\n hash2 = " << std::hex << hh[0] << std::hex << hh[1] << std::hex << hh[2] <<
std::hex << hh[3] << std::hex << hh[4] << std::hex << hh[5] << std::hex << hh[6] <<
std::hex << hh[7] << "\n\n";


for (z = 8; z < 16; z++) // записываем значения во временную переменную с 8 по 15
{
w_temp[z] = hh[z-8];
}


// 3. хеш от хешей первой и второй части //а куда вписывать бит "1" и длину?

for (z = 0; z < 16; z++) // сводим в массив значения хешей первой и второй частей
{
w[z] = w_temp[z];
}

std::cout << "\n";
for (z = 0; z < 16; z++) // смотрим значение 3 сообщения, которое преобразовываем
{
std::cout << w[z];
}
std::cout << " - 3 message\n";

func_sha256();

std::cout << "\n\n hash3= 1and2 = " << std::hex << hh[0] << std::hex << hh[1] << std::hex << hh[2] <<
std::hex << hh[3] << std::hex << hh[4] << std::hex << hh[5] << std::hex << hh[6] <<
std::hex << hh[7] << "\n\n";

}

это библиотека констант "const_sha256.h"
Кликните здесь для просмотра всего текста

#pragma once
/** Initialize SHA-256 const. */
// h0...7 - квадратные корни дробной части первых 8ми простых чисел
// k[64] - кубические корни дробной части первых 64 простых чисел


uint32_t h0 = 0x6a09e667;
uint32_t h1 = 0xbb67ae85;
uint32_t h2 = 0x3c6ef372;
uint32_t h3 = 0xa54ff53a;
uint32_t h4 = 0x510e527f;
uint32_t h5 = 0x9b05688c;
uint32_t h6 = 0x1f83d9ab;
uint32_t h7 = 0x5be0cd19;

uint32_t k[64] =
{
0x428a2f98,
0x71374491,
0xb5c0fbcf,
0xe9b5dba5,
0x3956c25b,
0x59f111f1,
0x923f82a4,
0xab1c5ed5,
0xd807aa98,
0x12835b01,
0x243185be,
0x550c7dc3,
0x72be5d74,
0x80deb1fe,
0x9bdc06a7,
0xc19bf174,

0xe49b69c1,
0xefbe4786,
0x0fc19dc6,
0x240ca1cc,
0x2de92c6f,
0x4a7484aa,
0x5cb0a9dc,
0x76f988da,
0x983e5152,
0xa831c66d,
0xb00327c8,
0xbf597fc7,
0xc6e00bf3,
0xd5a79147,
0x06ca6351,
0x14292967,

0x27b70a85,
0x2e1b2138,
0x4d2c6dfc,
0x53380d13,
0x650a7354,
0x766a0abb,
0x81c2c92e,
0x92722c85,
0xa2bfe8a1,
0xa81a664b,
0xc24b8b70,
0xc76c51a3,
0xd192e819,
0xd6990624,
0xf40e3585,
0x106aa070,

0x19a4c116,
0x1e376c08,
0x2748774c,
0x34b0bcb5,
0x391c0cb3,
0x4ed8aa4a,
0x5b9cca4f,
0x682e6ff3,
0x748f82ee,
0x78a5636f,
0x84c87814,
0x8cc70208,
0x90befffa,
0xa4506ceb,
0xbef9a3f7,
0xc67178f2
};


ps. Стандартную библиотеку биткоина видел, не осилил. Пока не осилил. Думаю видевшие ЭТО меня поймут

В конце темы (когда получится) будет правильный код.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.04.2021, 12:43
Ответы с готовыми решениями:

Алгоритм хеширования SHA256
Помогите разобраться Например есть случайная строка из 64 символов, символы это цифры 0-9 и буквы a-f. Что делает алгоритм хеширования...

Python скрипт генерации адресов BTC + Opencl в питоне для ускорения SHA256 , Scrypt , SHA256
Суть вот в чем, есть скрипт с виду должен работать но не сверяет input c генерированными данными просто молча генерит &quot;альфа...

Алгоритм хеш функции SHA256. Разбор кода
Найден в интернете код алгортима SHA256, помогите разобраться в коде, что подается на вход, где начало и т.д.. Как переделать в...

1
0 / 0 / 0
Регистрация: 10.06.2019
Сообщений: 7
19.04.2021, 23:06  [ТС]
Доброго всем.

Победил, выкладываю. Никакого ООП, все "по-деревенски", я еще не дочитал до темы "классы-методы"

Итого для биткоина необходимо 3 итерации. Пример выводит для всех итераций:
- сообщение, подвергаемое хешированию,
- первое значение константы для хеширования,
- сам хеш.

Сдобрил все большим количеством комментариев. Библиотека констант "const_sha256.h" в первом сообщении.

Кликните здесь для просмотра всего текста

#include <bitset>
#include <iostream>
#include <charconv>

#include "const_sha256.h" //константы АНБ

char version[9] = "02000000"; // Block 125552 без инверсии байтов
char prev_block[65] = "17975b97c18ed1f7e255adf297599b55330edab 87803c8170100000000000000";
char merkle_root[65] = "8a97295a2747b4f1a0b3948df3990344c0e19fa 6b2b92b3a19c8e6badc141787";
char timestamp[9] = "358b0553";
char bits[9] = "535f0119";
char nonce[9] = "48750833";

uint32_t mess[20]; // входящия массив слов (20 слов по 8 символов или по 32 бита)
uint32_t w[64]; // 64 слова, используемые в программе

int i = 0, z = 0;

uint32_t s0 = 0, s1 = 0; //переменные необходимые для преобразований
uint32_t a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
uint32_t ch = 0, maj = 0, temp1 = 0, temp2 = 0;

uint32_t hh[8]; //для временного хранения наших хешей в циклах хеширования


void func_sha256()
{
// Начинаем цикл хеширования, в цикле составляем 48 слов (w[i]), с 16-го по 63-е
for (i = 16; i < 64; i++)
{
s0 = (((w[i - 15] >> 7) | (w[i - 15] << (32 - 7))) //rightrotate 7 for s0
^ ((w[i - 15] >> 18) | (w[i - 15] << (32 - 18))) //rightrotate 18 for s0
^ (w[i - 15] >> 3)); // XOR for s0 //rightshift 3 for s0

s1 = (((w[i - 2] >> 17) | (w[i - 2] << (32 - 17))) //rightrotate 17 for s1
^ ((w[i - 2] >> 19) | (w[i - 2] << (32 - 19))) //rightrotate 19 for s1
^ (w[i - 2] >> 10)); // XOR for s1 //rightshift 10 for s1

w[i] = w[i - 16] + s0 + w[i - 7] + s1;
}


a = h0; // цикл сжатия
b = h1; //Установим первоначальные значения равными константам АНБ
c = h2;
d = h3;
e = h4;
f = h5;
g = h6;
h = h7;

for (i = 0; i < 64; i++)
{
s1 = (((e >> 6) | (e << (32 - 6))) //rightrotate 6 for e
^ ((e >> 11) | (e << (32 - 11))) //rightrotate 11 for e
^ ((e >> 25) | (e << (32 - 25)))); // XOR //rightrotate 25 for e
ch = (e & f) | (~e & g); // (e and f) xor ((not e) and g)
temp1 = h + s1 + ch + k[i] + w[i];


s0 = (((a >> 2) | (a << (32 - 2))) //rightrotate 2 for a
^ ((a >> 13) | (a << (32 - 13))) //rightrotate 13 for a
^ ((a >> 22) | (a << (32 - 22)))); // XOR //rightrotate 22 for a
maj = (a & b) | (a & c) | (b & c); // (a and b) xor (a and c) xor (b and c)
temp2 = s0 + maj;

h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}

std::cout << "\n\n ___h0___ = " << std::hex << h0;

hh[0] = h0 + a;
hh[1] = h1 + b;
hh[2] = h2 + c;
hh[3] = h3 + d;
hh[4] = h4 + e;
hh[5] = h5 + f;
hh[6] = h6 + g;
hh[7] = h7 + h;
}



int main()
{ // проверьте! для from_chars версия С++ не ниже 17
std::from_chars(version, version + 8, mess[0], 16); // mess[0] = version

std::from_chars(prev_block, prev_block + 8, mess[1], 16); // mess[1..8] = prev_block
std::from_chars(prev_block + 8, prev_block + 16, mess[2], 16);
std::from_chars(prev_block + 16, prev_block + 24, mess[3], 16);
std::from_chars(prev_block + 24, prev_block + 32, mess[4], 16);
std::from_chars(prev_block + 32, prev_block + 40, mess[5], 16);
std::from_chars(prev_block + 40, prev_block + 48, mess[6], 16);
std::from_chars(prev_block + 48, prev_block + 56, mess[7], 16);
std::from_chars(prev_block + 56, prev_block + 64, mess[8], 16);

std::from_chars(merkle_root, merkle_root + 8, mess[9], 16); // mess[9..16] = merkle_root
std::from_chars(merkle_root + 8, merkle_root + 16, mess[10], 16);
std::from_chars(merkle_root + 16, merkle_root + 24, mess[11], 16);
std::from_chars(merkle_root + 24, merkle_root + 32, mess[12], 16);
std::from_chars(merkle_root + 32, merkle_root + 40, mess[13], 16);
std::from_chars(merkle_root + 40, merkle_root + 48, mess[14], 16);
std::from_chars(merkle_root + 48, merkle_root + 56, mess[15], 16);
std::from_chars(merkle_root + 56, merkle_root + 64, mess[16], 16);

std::from_chars(timestamp, timestamp + 8, mess[17], 16); // mess[17] = timestamp

std::from_chars(bits, bits + 8, mess[18], 16); // mess[18] = bits (сложность)

std::from_chars(nonce, nonce + 8, mess[19], 16); // mess[19] = nonce




std::cout << "\n " << std::hex << mess[0];
std::cout << "\n " << std::hex << mess[1] << mess[2] << mess[3] << mess[4] <<
mess[5] << mess[6] << mess[7] << mess[8];
std::cout << "\n " << std::hex << mess[9] << mess[10] << mess[11] << mess[12] <<
mess[13] << mess[14] << mess[15] << mess[16];
std::cout << "\n " << std::hex << mess[17];
std::cout << "\n " << std::hex << mess[18];
std::cout << "\n " << std::hex << mess[19];
std::cout << "\n\n";




// 1. хеш первой части сообщения (midstate)
std::cout << "\n___________________1_________________ __\n";

for (z = 0; z < 16; z++) // значение сообщения, которое преобразовываем
{
w[z] = mess[z];
}


std::cout << "\n";
for (z = 0; z < 16; z++) // смотрим значение 1 сообщения, которое преобразовываем
{
std::cout << w[z];
}
std::cout << " - 1 message";



func_sha256();

std::cout << "\n\n hash1 = " << std::hex << hh[0] << std::hex << hh[1] << std::hex << hh[2] <<
std::hex << hh[3] << std::hex << hh[4] << std::hex << hh[5] << std::hex << hh[6] <<
std::hex << hh[7] << "\n\n";

uint32_t w_temp[16]; // записываем значения во временную переменную с 0 по 7
for (z = 0; z < 8; z++)
{
w_temp[z] = hh[z]; // первый хеш
}



// 2. хеш второй части сообщения
std::cout << "\n______________________2______________ ___\n";
for (z = 0; z < 4; z++)
{
w[z] = mess[z + 16]; // первые 4ре значения значение 2 сообщения
}

for (z = 4; z < 16; z++)
{
w[z] = 0;
}

w[4] = 0x80000000; //добавляем последним значением массива '1_с 31 нулем'
// так как нужно добавить последним 1 БИТ, поэтому 10000...00, а не 0000 0001

// записываем длину сообщения в 34-е и 35 слово как 0000 0010 1000 0000 (640 бит в dec)
w[15] = 640; // (16 + 4) * 32, это 20 слов по 32 бита

h0 = w_temp[0]; // особенность хеширования второй части:
h1 = w_temp[1]; // вместо констант из sha256 используются результат
h2 = w_temp[2]; // первого хеша
h3 = w_temp[3];
h4 = w_temp[4];
h5 = w_temp[5];
h6 = w_temp[6];
h7 = w_temp[7];

std::cout << "\n";
for (z = 0; z < 16; z++) // смотрим значение 2 сообщения, которое преобразовываем
{
std::cout << w[z];
}
std::cout << " - 2 message";

func_sha256();

std::cout << "\n\n hash2 = " << std::hex << hh[0] << std::hex << hh[1] << std::hex << hh[2] <<
std::hex << hh[3] << std::hex << hh[4] << std::hex << hh[5] << std::hex << hh[6] <<
std::hex << hh[7] << "\n\n";


for (z = 8; z < 16; z++) // записываем значения во временную переменную с 8 по 15
{
w_temp[z] = hh[z-8]; // второй хеш
}


// 3. хеш результата второго хеша. Снова с помошью стандартных констант
std::cout << "\n____________________3________________ __\n";

h0 = 0x6a09e667; // с помощью стандартных констант
h1 = 0xbb67ae85;
h2 = 0x3c6ef372;
h3 = 0xa54ff53a;
h4 = 0x510e527f;
h5 = 0x9b05688c;
h6 = 0x1f83d9ab;
h7 = 0x5be0cd19;

for (z = 0; z < 8; z++) // массив значения хешей - результат второго хеширования
{
w[z] = hh[z];
}

w[8] = 2147483648; //добавляем последним значением массива '1_с 31 нулем'
// так как нужно добавить последним 1 БИТ, поэтому 1000 0000 а не 0000 0001

// записываем длину сообщения
w[15] = 256; // 8 * 32, это 8 слов по 32 бита = 256 бит в dec или 1 0000 0000 в бинарной

std::cout << "\n";
for (z = 0; z < 16; z++) // смотрим значение 3 сообщения, которое преобразовываем
{
std::cout << w[z];
}
std::cout << " - 3 message";

func_sha256();

std::cout << "\n\n hash3= 1and2 = " << std::hex << hh[0] << std::hex << hh[1] << std::hex << hh[2] <<
std::hex << hh[3] << std::hex << hh[4] << std::hex << hh[5] << std::hex << hh[6] <<
std::hex << hh[7] << "\n\n";

for (z = 0; z < 8; z++) // выводим построчно каждое слово результата
{
std::cout << "\n hh[" << z << "] = " << std::hex << hh[z] << " = " << std::bitset<32>(hh[z]);
}

}
// последняя операция - переворот байтов парами, чтобы нули были вначале
// (для складирования в базу правильных решений биткоина), но уже поздно, спать пора
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.04.2021, 23:06
Помогаю со студенческими работами здесь

Wincript, падает программа при получении SHA256
Делаю так: BYTE * pbHash; // Хэш WCHAR * wHex; // hex хэша пароля DWORD dwHashLen; // Длина хэш суммы HCRYPTPROV hProv =...

Представление списка строк в виде, понятном интерпретатору Питона
Напишите программу — помощник начинающего программиста на Питоне, которая представляет список строк в виде, понятном интерпретатору Питона....

Не получается понять джаву
Здравствуйте! Нужна программа которая выполняет это: a. Сгенерируйте числовой ряд длиной не более 50, представляющий собой числа...

Пытаюсь понять, не получается
По запросу - Магазины Ярославля 4-9 места занимают какие-то левые сайты, причем в описании присутствует название моего сайта - Магазины...

Приватные и публичные ключи в трансзакции биткоина
Что-то не могу понять про ключи в битконе. Есть приватный ключ для входа в кошелек - он постоянный. Есть публичный ключ, из него сделан...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru