LINUX.ORG.RU

Только std::to_string, только хардкор

annulen ★★★★★
()

Вот что есть

#include <iostream>
#include <vector>
#include <fstream>  
//#include <stdlib.h>   
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
#define N 8
#define F32 0xFFFFFFFF
#define size64 sizeof(uint64_t)
#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))
#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))
#define RKEY(r)((ROR(K,r*3,size64*8))&F32)
const uint64_t K = 0x96EA704CFB1CF672;//base key to forming of round keys
uint32_t RK[N];//massive round keys
void createRoundKeys(bool print)
{
	for (int i = 0; i < N; i++)
	{
		RK[i]=(ROR(K, i * 8, size64 * 8))&F32;
		if (print)
			std::cout << "key[" << i << "]=" << std::hex << RK[i] << std::endl;
	}
}
uint32_t F(uint32_t subblk, uint32_t key)
{
	/*
	uint32_t f1 = ROL(subblk, 9, sizeof(subblk) * 8);
	uint32_t f2 = ROR(key, 11, sizeof(key) * 8) | subblk;
	return f1 ^ !f2;
	*/
	return subblk+key;
}
//encryption 64-digit block of message
uint64_t encrypt(uint64_t block, bool print)
{
	//select subblocks
	uint32_t left = (block >> 32)&F32;
	uint32_t right = block&F32;

	uint32_t left_, right_;//subblock in the end of round
	for (int r = 0; r < N; r++)
	{
		if (print)
			std::cout << "round " << r << std::endl << "input blks " << std::hex << left << " " << right << std::endl;
		uint32_t fk = F(left, RK[r]);
		left_ = left;
		right_ = right^fk;
		if (r < N - 1)//swap places to next round
		{
			left = right_;
			right = left_;
		}
		else//last round not swap
		{
			left = left_;
			right = right_;
		}
		if (print)
			std::cout << "round" << r << std::endl << "output blks " << std::hex << left << " " << right << std::endl;
	}
	//collect subblock in block
	uint64_t c_block = left;
	c_block = (c_block << 32) | (right&F32);
	return c_block;
}
//decryption 64-digit block of message
uint64_t decrypt(uint64_t c_block, bool print)
{
	//select subblocks
	uint32_t left = (c_block >> 32)&F32;
	uint32_t right = c_block&F32;

	uint32_t left_, right_;//subblock in the end of round
	for (int r = N-1; r >=0; r--)
	{
		if (print)
			std::cout << "round " << r << std::endl << "input blks " << std::hex << left << " " << right << std::endl;
		uint32_t fk = F(left, RK[r]);
		left_ = left;
		right_ = right^fk;
		if (r > 0)//swap places to next round
		{
			left = right_;
			right = left_;
		}
		else //last round not swap
		{
			left = left_;
			right = right_;
		}
		if (print)
			std::cout << "round" << r << std::endl << "output blks " << std::hex << left << " " << right << std::endl;
	}
	//collect subblock in block
	uint64_t block = left;
	block = (block << 32) | (right&F32);
	return block;
}

void main()
{
	std::cout << "Base key\n" <<std::hex<<K<< std::endl;
	std::cout << "\nRound keys:" << std::endl;
	createRoundKeys(false);
	/*
	FILE *fp;
	char str[64];
	if ((fp=fopen("message.txt", "r") )==NULL) {
		//printf("Cannot open file.\n");
		std::cout<<"Cannot open file.\n";
		exit (1);
	}
	*/
	std::vector<uint64_t> *msg = new std::vector<uint64_t>(),*plaintext = new std::vector<uint64_t>();//plain text
	/*
	while(!feof (fp)) {
		if (fgets(str, 64, fp))
		{	
			//printf("%s", str);
			std::cout<<str;
			msg->push_back(std::atol(str));
		}
	}
	*/
	unsigned long long id; 
	{ 
		std::ifstream in("message.txt"); 
		in >> id; 
		msg->push_back(id);		
	} 
	//uint64_t msg = 0xFFAADD11CCBB2299;//plain text
	//msg->push_back(0xFFAADD11CCBB2299);
	//msg->push_back(0xFFAADD11CCBB2288);
	//msg->push_back(0xFFAADD11CCBB2277);
	
	//fclose(fp);
	int ii=0;
	for (std::vector<uint64_t>::iterator it = msg->begin() ; it != msg->end(); ++it)
	{
		std::cout << "msg:\n" << std::hex << *it<< std::endl;
	//}
	//std::cout << "msg:\n" << std::hex << msg << std::endl;
	//uint64_t cipher = encrypt(msg, true);//change on true second parameter when debug, ciphertext
	uint64_t cipher = encrypt(msg->at(ii), false);//change on true second parameter when debug, ciphertext
	ii++;
	std::cout << "encrypt:\n" << cipher << std::endl;
	//msg = decrypt(cipher, true);//change on true second parameter when debug,plain text
	plaintext->push_back(decrypt(cipher, false));//change on true second parameter when debug,plain text

	std::ofstream out("message2.txt"); 
	out << plaintext->at(ii); 

	//std::cout << "decrypt:\n" << msg<< std::endl;
	//for (std::vector<uint64_t>::iterator it = plaintext->begin() ; it != plaintext->end(); ++it)
	//{
		std::cout << "decrypt:\n" << *it<<"--------------------------\n\n"<< std::endl;
	}
	
	system("pause");
}

Gremlin_
() автор топика

Я ничего не понял, но

long long strToLL(char* str) {
    long long t = 1;
    long long ret = 0;
    for (int i = 0; i < 64; i++) {
        long long add = str[i] - 49;
        ret += add * t;
        t *= 10;
    }
    return ret;
}
Число в str должно подаваться задом наперёд то есть не «110», а «011». Обратное преобразование сам запилишь.

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Шифрование файла с текстом message , и расшифровка его в message2, с помощью сети фейстеля 8 раундов, 2 ветви

Gremlin_
() автор топика
Ответ на: комментарий от Gremlin_

Ну, короче, смотри.

int hexCharToInt(char c) {
   char* vars="0123456789ABCDEF";
   int i;
   for (i = 0; i < 16; i++) if (*vars[i] == c) break;
   return i;
}
char intToHexChar(int i) {
   char* vars="0123456789ABCDEF";
   return *vars[i%16];
}
long long strToLL(char* str) {
    long long t = 1;
    long long ret = 0;
    for (int i = 0; i < 64; i++) {
        long long add = hexCharToInt(*str[i]);
        ret += add * t;
        t *= 16;
    }
    return ret;
}
А с long long to hex просто сделай printf в hex и обрежь его, если надо.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от Gremlin_

Да нафиг делать каст? Одумайся, так не интересно. Вот копипаста с switch бы зашла, но это слишком тупо.

crutch_master ★★★★★
()
Ответ на: комментарий от Gremlin_

Ну читаешь ты его в long long? А long long - это 64 бита. Хотя лучше использовать uint64, но кому они нужны.

crutch_master ★★★★★
()
Ответ на: комментарий от Gremlin_

А, у тебя есть uint_64t

typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
Мухахахахахаха.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от anonymous

Паттерн for-if Вы специально предлагаете вместо if (/* not overflow */) return vars[c];?

Я не вполне понимаю, какую задачу надо решить. Вроде бы надо 8 штук uint8 перегнать в uint64. Ну да, я специально сделал этот «словарь» типа чтобы было понятно.

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Вот смотри код, почти решил сообщение->зашифровка->расшифровка, то бишь берем небольшой текст на английском языке в message.txt потом ждем работу программы cryptmessage.txt и message2.txt , message=message2 должно быть

#include <iostream>
#include <vector>
#include <fstream>  
//#include <stdlib.h>   
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
#define N 8
#define F32 0xFFFFFFFF
#define size64 sizeof(uint64_t)
#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))
#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))
#define RKEY(r)((ROR(K,r*3,size64*8))&F32)
const uint64_t K = 0x96EA704CFB1CF672;//base key to forming of round keys
uint32_t RK[N];//massive round keys
void createRoundKeys(bool print)
{
	for (int i = 0; i < N; i++)
	{
		RK[i]=(ROR(K, i * 8, size64 * 8))&F32;
		if (print)
			std::cout << "key[" << i << "]=" << std::hex << RK[i] << std::endl;
	}
}
uint32_t F(uint32_t subblk, uint32_t key)
{
	/*
	uint32_t f1 = ROL(subblk, 9, sizeof(subblk) * 8);
	uint32_t f2 = ROR(key, 11, sizeof(key) * 8) | subblk;
	return f1 ^ !f2;
	*/
	return subblk+key;
}
//encryption 64-digit block of message
uint64_t encrypt(uint64_t block, bool print)
{
	//select subblocks
	uint32_t left = (block >> 32)&F32;
	uint32_t right = block&F32;

	uint32_t left_, right_;//subblock in the end of round
	for (int r = 0; r < N; r++)
	{
		if (print)
			std::cout << "round " << r << std::endl << "input blks " << std::hex << left << " " << right << std::endl;
		uint32_t fk = F(left, RK[r]);
		left_ = left;
		right_ = right^fk;
		if (r < N - 1)//swap places to next round
		{
			left = right_;
			right = left_;
		}
		else//last round not swap
		{
			left = left_;
			right = right_;
		}
		if (print)
			std::cout << "round" << r << std::endl << "output blks " << std::hex << left << " " << right << std::endl;
	}
	//collect subblock in block
	uint64_t c_block = left;
	c_block = (c_block << 32) | (right&F32);
	return c_block;
}
//decryption 64-digit block of message
uint64_t decrypt(uint64_t c_block, bool print)
{
	//select subblocks
	uint32_t left = (c_block >> 32)&F32;
	uint32_t right = c_block&F32;

	uint32_t left_, right_;//subblock in the end of round
	for (int r = N-1; r >=0; r--)
	{
		if (print)
			std::cout << "round " << r << std::endl << "input blks " << std::hex << left << " " << right << std::endl;
		uint32_t fk = F(left, RK[r]);
		left_ = left;
		right_ = right^fk;
		if (r > 0)//swap places to next round
		{
			left = right_;
			right = left_;
		}
		else //last round not swap
		{
			left = left_;
			right = right_;
		}
		if (print)
			std::cout << "round" << r << std::endl << "output blks " << std::hex << left << " " << right << std::endl;
	}
	//collect subblock in block
	uint64_t block = left;
	block = (block << 32) | (right&F32);
	return block;
}
#pragma warning(disable:4996)
void main()
{
	std::cout << "Base key\n" <<std::hex<<K<< std::endl;
	std::cout << "\nRound keys:" << std::endl;
	createRoundKeys(false);
	
	FILE *fp,*fencrypted,*fdecrypted;
	char str[8];
	if ((fp=fopen("message.txt", "r" ))==NULL) {
		//printf("Cannot open file.\n");
		std::cout<<"Cannot open file.\n";
		exit (1);
	}
	
	std::vector<uint64_t> *msg = new std::vector<uint64_t>(),*plaintext = new std::vector<uint64_t>();//plain text

	unsigned long long id;
	while(!feof (fp)) {
		if (fgets(str, 8, fp))
		{	
			//printf("%s", str);
			std::cout<<str;
			memcpy(&id, str, 8/*sizeof(str)*/);
			msg->push_back(id);
		}
	}
	
	/*
	unsigned long long id; 
	{ 
		std::ifstream in("message.txt"); 
		in >> id; 
		msg->push_back(id);		
	} 
	*/
	//uint64_t msg = 0xFFAADD11CCBB2299;//plain text
	//msg->push_back(0xFFAADD11CCBB2299);
	//msg->push_back(0xFFAADD11CCBB2288);
	//msg->push_back(0xFFAADD11CCBB2277);
	
	fclose(fp);
	int ii=0;
	if ((fencrypted = fopen("cryptmessage.txt", "w")) == NULL) {
		//printf("Cannot open file.\n");
		std::cout << "Cannot open file.\n";
		exit(1);
	}
	if ((fdecrypted = fopen("message2.txt", "w")) == NULL) {
		//printf("Cannot open file.\n");
		std::cout << "Cannot open file.\n";
		exit(1);
	}
	for (std::vector<uint64_t>::iterator it = msg->begin() ; it != msg->end(); ++it)
	{
		std::cout << "msg:\n" << std::hex << *it<< std::endl;
		//std::cout << "msg:\n" << std::hex << msg << std::endl;
		//uint64_t cipher = encrypt(msg, true);//change on true second parameter when debug, ciphertext
		uint64_t cipher = encrypt(msg->at(ii), false);//change on true second parameter when debug, ciphertext
		
		std::cout << "encrypt:\n" << cipher << std::endl;
		memcpy(str, &cipher, sizeof(cipher));
		fwrite(str, sizeof(str),1, fencrypted);
		//msg = decrypt(cipher, true);//change on true second parameter when debug,plain text
		plaintext->push_back(decrypt(cipher, false));//change on true second parameter when debug,plain text

		memcpy(str, &plaintext->at(ii), sizeof(cipher));
		fwrite(str,sizeof(str),1, fdecrypted);

		//std::cout << "decrypt:\n" << msg<< std::endl;
		std::cout << "decrypt:\n" <<plaintext->at(ii)<< "\n--------------------------\n" << std::endl;
		ii++;
	}
	fclose(fencrypted);
	fclose(fdecrypted);
	system("pause");
}

Gremlin_
() автор топика
Ответ на: комментарий от crutch_master

Ну в мэйн функции, дергаются функции сначала encrypt, after decrypt и результаты в файл пишутся поблочно,по 8 байт, тобишь 7 символов и последний нуль-символ, в этом и проблема нули в конце каждого блока дают то пробел то символ Nul смотря в каком текстовом редакторе открывать message2, вся проблема спрятана в функции fgets и наверное немного в fwrite, потому что последний блок целиком не влезит точнее влезет и оставшиеся чары надо нулями добить

Gremlin_
() автор топика
Ответ на: комментарий от Gremlin_

Короче вначале берётся текст из файла message(можно взять любой бред с википедии английской пару предложений и вставить в текстовом редакторе в этот файл и сохранить) потом делается шифрование(encrypt) по 8 байт считывается функцией fgets из файла message, результат этого записывается в файл cryptmessage также по 8байт(потому что шифр блочный-сеть фейстеля), далее происходит расшифровка decrypt в файл fwrite message2 , но дело в том что нуль символы(null) переходят то в пробелы то ещё в чето

Gremlin_
() автор топика
Ответ на: комментарий от crutch_master

Из массива char* в unsigned long long после считывания message я уже перевёл для шифровки функцией memcpy cryptmessage и обратно для записи в файл message2

Gremlin_
() автор топика
Ответ на: комментарий от crutch_master
if ((fp=fopen("message.txt", "r" ))==NULL) {
		//printf("Cannot open file.\n");
		std::cout<<"Cannot open file.\n";
		exit (1);
	}
	
	std::vector<uint64_t> *msg = new std::vector<uint64_t>(),*plaintext = new std::vector<uint64_t>();//plain text

	unsigned long long id;
	while(!feof (fp)) {
		if (fgets(str, 8, fp))
		{	
			//printf("%s", str);
			std::cout<<str;
			memcpy(&id, str, 8/*sizeof(str)*/);
			msg->push_back(id);
		}
	}

считывает сообщение из месседж в чары, преобразуются в unsigned long long с помощью функции memcpy,далее для того чтобы зашифровать нужно не в чарах работать а в 64битных числах, весь текст преобразуется в эти числа и добавляются в вектор msg,

uint64_t cipher = encrypt(msg->at(ii), false);//change on true second parameter when debug, ciphertext
		
		std::cout << "encrypt:\n" << cipher << std::endl;
		memcpy(str, &cipher, sizeof(cipher));
		fwrite(str, sizeof(str),1, fencrypted);
потом эти числа шифруются функцией encrypt и результат переводится в строки и записывается в файл cryptmessage,
plaintext->push_back(decrypt(cipher, false));//change on true second parameter when debug,plain text

		memcpy(str, &plaintext->at(ii), sizeof(cipher));
		fwrite(str,sizeof(str),1, fdecrypted);
,далее дешифруется функцией decrypt и записывается в файл message2 и наконец мы видим что файлы message и message2(открой их в текстовом редакторе например gedit) не много не совпадают в чем проблема?

Gremlin_
() автор топика
Ответ на: комментарий от Gremlin_

во втором абзаце забыл упомянуть что строки и файла cryptmessage можно передать например по сети и никто их не разберёт

Gremlin_
() автор топика
Ответ на: комментарий от crutch_master

Вроде одно число правильно преобразует туда-назад:

	//uint64_t msg = 0xFFAADD11CCBB2299;//plain text

Gremlin_
() автор топика
Ответ на: комментарий от crutch_master

Скинь скрины текста который получился у тебя до и после, а насчет разбирания ну например по коду все нормально, я вот не могу только понять зачем F32

Gremlin_
() автор топика
Ответ на: комментарий от crutch_master

например используя этот plaintext (закинь в файл message.txt)

The fgets () function reads up to num-1 characters
 from the stream file and places them in
 the character array pointed to by str. Characters 
are read until a “new line” character is encountered, 
EOF, or until the specified limit is reached. When 
the read is completed, the zero character is placed 
in the str array immediately after the last character
 read. The “new line” character when read will be 
saved and will become part of the str array.

Gremlin_
() автор топика
Ответ на: комментарий от crutch_master

я б тебе скинул фото, но сейчас за другим компом

Gremlin_
() автор топика
Ответ на: комментарий от Gremlin_
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;

Зачем? Уже два десятилетия прошло, как появился stdint.h/cstdint. Мне страшно читать дальше

XMs ★★★★★
()
Ответ на: комментарий от Gremlin_

как-то так

«сейчас» ты можешь только внимательно вычитывать свое сообщение до публикации. если, всё же поместил, а затем решил изменить, то нужно успеть удалить до ответа и написать заново.

anymouze ★★
()
Ответ на: как-то так от anymouze

Да пох, а по сабжу подберу длину нужную и все будет ок

Gremlin_
() автор топика
Ответ на: комментарий от Gremlin_

Ну смотря какой компилятор

Это давно в стандарте, сынок.

Из статьи Википедии «C99»

In March 2000, ANSI adopted the ISO/IEC 9899:1999[9] standard. This standard is commonly referred to as C99. Some notable additions to the previous standard include:

New built-in data types: long long, _Bool, _Complex, and _Imaginary Several new core language features, including static array indices, designated initializers, compound literals, variable-length arrays, flexible array members, variadic macros, and restrict keyword Several new library headers, including stdint.h, <tgmath.h>, fenv., <complex.h>

LongLiveUbuntu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.