//55 47 28 00 29 87 1C 00 07 00 07 00 B5 0E 00 00 17 00 00 00 17 00 00 00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF E0 F5 05 - число 99999999
//55 47 28 00 7C 9F 1C 00 07 00 07 00 B1 C2 00 00 17 00 00 00 17 00 00 00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 - число 1
//55 47 28 00 00 00 1C 00 07 00 07 00 6F D2 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 32 00 00 00 - число 50
//55 47 28 00 00 00 1C 00 07 00 07 00 5D 8B 00 00 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 - число 256
Помогите осилить алгоритм преобразования числа в байты
http://pachkov.ru/wp-content/uploads/2008/03/windows_vista.jpg картинка, только в отношении к подобным преобразованиям.
суть проблемы в том, что есть у меня массив из 44 байтов к примеру.
не важно что он хранит, важно что последние 4 байта отвечают за число.
вот пара примеров:
мне надо туда записывать свои числа... в эти последние 4 байта.
возникает огромное множество проблем, связанных с тем, каким образом разбить число так на байты и записать...
в wpf к примеру есть замечательная функция pint которая и занимается подобными вещами.
к примеру в результате pint(buf, 50, 40, 4);
50 - число которое преобразовать
40 - начальный элемент массива
4 количество байт отведенных под число
массив с неважно какими последними 4 байтами превратится в
я пытался сделать такой же аналог... ну или хотя бы получить массив из 4 байт, где бы хранилось то что мне надо (32 00 00 00 к примеру).
просидел весь день пытаясь сделать все возможные методы конветирования этих штук %)
последний вариант моей хрени
все работает не так как надо с начала и до конца %)
Смысла говорить что получается нет, так как ничего адекватного не получается вообще.
Может кто-то помочь с адекватным алгоритмом таких преобразований?
так чтоб на входе было число 50 к примеру, а на выходе массив из 4 байт {32, 00, 00, 00}
на входе 256, на выходе {00, 01, 00, 00}
Сразу вспомнилась эта
суть проблемы в том, что есть у меня массив из 44 байтов к примеру.
не важно что он хранит, важно что последние 4 байта отвечают за число.
вот пара примеров:
Код:
мне надо туда записывать свои числа... в эти последние 4 байта.
возникает огромное множество проблем, связанных с тем, каким образом разбить число так на байты и записать...
в wpf к примеру есть замечательная функция pint которая и занимается подобными вещами.
к примеру в результате pint(buf, 50, 40, 4);
50 - число которое преобразовать
40 - начальный элемент массива
4 количество байт отведенных под число
массив с неважно какими последними 4 байтами превратится в
Код:
//55 47 28 00 00 00 1C 00 07 00 07 00 5D 8B 00 00 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 32 00 00 00
я пытался сделать такой же аналог... ну или хотя бы получить массив из 4 байт, где бы хранилось то что мне надо (32 00 00 00 к примеру).
просидел весь день пытаясь сделать все возможные методы конветирования этих штук %)
последний вариант моей хрени
Код:
// TestPacket.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <string>
#include <bitset>
#include <sstream>
char* double_to_hex_string(double value)
{
static char result[1000];
char *p = result;
char *p_bound = p + sizeof(result) - 1;
double v = value;
double a = 1.0;
if( v < 0 ) return "(value is negative)";
while( a * 16 <= v ) a *= 16;
while( a >= 1 )
{
int m;
for( m = 0; m < 16 && (m + 1) * a <= v; m++ ) {}
if( p < p_bound ) *p++ = "0123456789abcdef"[ m ], *p = 0;
v -= m * a;
a /= 16;
}
return result;
}
void string_to_bytearray(std::string str, unsigned char* &array, int& size)
{
int length = str.length();
// make sure the input string has an even digit numbers
if(length % 2 == 1)
{
str = "0" + str;
length++;
}
// allocate memory for the output array
array = new unsigned char[length / 2];
size = length / 2;
std::stringstream sstr(str);
for(int i = 0; i < size; i++)
{
char ch1, ch2;
sstr >> ch1 >> ch2;
int dig1, dig2;
if(isdigit(ch1)) dig1 = ch1 - '0';
else if(ch1 >= 'A' && ch1 <= 'F') dig1 = ch1 - 'A' + 10;
else if(ch1 >= 'a' && ch1 <= 'f') dig1 = ch1 - 'a' + 10;
if(isdigit(ch2)) dig2 = ch2 - '0';
else if(ch2 >= 'A' && ch2 <= 'F') dig2 = ch2 - 'A' + 10;
else if(ch2 >= 'a' && ch2 <= 'f') dig2 = ch2 - 'a' + 10;
array = dig1 * 16 + dig2;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
//unsigned char* buf = NULL;
//int size;
//BYTE* temp = (BYTE*)double_to_hex_string(50);
char hex_num[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
BYTE inv_hex_num[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
BYTE result_num[] = { 0, 0, 0, 0 };
itoa(256, hex_num, 16);
if (strlen(hex_num) % 2 == 1)
{
char temp[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
temp[0] = 0;
for (int i = 1; i < 8; i++)
temp = hex_num[i - 1];
memcpy(hex_num, temp, 8);
}
for(int i = 0; i < 8; i++)
inv_hex_num[7 - i] = hex_num;
memcpy(hex_num, inv_hex_num, 8);
std::string hex_num_str = "";
if (hex_num[7] != 0) hex_num_str += hex_num[7];
hex_num_str += hex_num[6];
result_num[3] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
hex_num_str.clear();
if (hex_num[5] != 0) hex_num_str += hex_num[5];
hex_num_str += hex_num[4];
result_num[2] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
hex_num_str.clear();
if (hex_num[3] != 0) hex_num_str += hex_num[3];
hex_num_str += hex_num[2];
result_num[1] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
hex_num_str.clear();
if (hex_num[1] != 0) hex_num_str += hex_num[1];
hex_num_str += hex_num[0];
result_num[0] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
//string_to_bytearray(hex_num, buf, size);
//int i = 0;
//delete [] buf;
return 0;
}
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <string>
#include <bitset>
#include <sstream>
char* double_to_hex_string(double value)
{
static char result[1000];
char *p = result;
char *p_bound = p + sizeof(result) - 1;
double v = value;
double a = 1.0;
if( v < 0 ) return "(value is negative)";
while( a * 16 <= v ) a *= 16;
while( a >= 1 )
{
int m;
for( m = 0; m < 16 && (m + 1) * a <= v; m++ ) {}
if( p < p_bound ) *p++ = "0123456789abcdef"[ m ], *p = 0;
v -= m * a;
a /= 16;
}
return result;
}
void string_to_bytearray(std::string str, unsigned char* &array, int& size)
{
int length = str.length();
// make sure the input string has an even digit numbers
if(length % 2 == 1)
{
str = "0" + str;
length++;
}
// allocate memory for the output array
array = new unsigned char[length / 2];
size = length / 2;
std::stringstream sstr(str);
for(int i = 0; i < size; i++)
{
char ch1, ch2;
sstr >> ch1 >> ch2;
int dig1, dig2;
if(isdigit(ch1)) dig1 = ch1 - '0';
else if(ch1 >= 'A' && ch1 <= 'F') dig1 = ch1 - 'A' + 10;
else if(ch1 >= 'a' && ch1 <= 'f') dig1 = ch1 - 'a' + 10;
if(isdigit(ch2)) dig2 = ch2 - '0';
else if(ch2 >= 'A' && ch2 <= 'F') dig2 = ch2 - 'A' + 10;
else if(ch2 >= 'a' && ch2 <= 'f') dig2 = ch2 - 'a' + 10;
array = dig1 * 16 + dig2;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
//unsigned char* buf = NULL;
//int size;
//BYTE* temp = (BYTE*)double_to_hex_string(50);
char hex_num[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
BYTE inv_hex_num[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
BYTE result_num[] = { 0, 0, 0, 0 };
itoa(256, hex_num, 16);
if (strlen(hex_num) % 2 == 1)
{
char temp[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
temp[0] = 0;
for (int i = 1; i < 8; i++)
temp = hex_num[i - 1];
memcpy(hex_num, temp, 8);
}
for(int i = 0; i < 8; i++)
inv_hex_num[7 - i] = hex_num;
memcpy(hex_num, inv_hex_num, 8);
std::string hex_num_str = "";
if (hex_num[7] != 0) hex_num_str += hex_num[7];
hex_num_str += hex_num[6];
result_num[3] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
hex_num_str.clear();
if (hex_num[5] != 0) hex_num_str += hex_num[5];
hex_num_str += hex_num[4];
result_num[2] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
hex_num_str.clear();
if (hex_num[3] != 0) hex_num_str += hex_num[3];
hex_num_str += hex_num[2];
result_num[1] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
hex_num_str.clear();
if (hex_num[1] != 0) hex_num_str += hex_num[1];
hex_num_str += hex_num[0];
result_num[0] = (BYTE)strtol(hex_num_str.c_str(), NULL, 16);
//string_to_bytearray(hex_num, buf, size);
//int i = 0;
//delete [] buf;
return 0;
}
все работает не так как надо с начала и до конца %)
Смысла говорить что получается нет, так как ничего адекватного не получается вообще.
Может кто-то помочь с адекватным алгоритмом таких преобразований?
так чтоб на входе было число 50 к примеру, а на выходе массив из 4 байт {32, 00, 00, 00}
на входе 256, на выходе {00, 01, 00, 00}
Может кто-то помочь с адекватным алгоритмом таких преобразований?
так чтоб на входе было число 50 к примеру, а на выходе массив из 4 байт {32, 00, 00, 00}
на входе 256, на выходе {00, 01, 00, 00}
[/QUOTE]
Числа целые?
Код:
unsigned char *pack_int(int X, unsigned char *buf) {
buf[0] = (X & 0x000000FF);
buf[1] = (X & 0x0000FF00) >> 8;
buf[2] = (X & 0x00FF0000) >> 16;
buf[3] = (X & 0xFF000000) >> 24;
return buf;
}
buf[0] = (X & 0x000000FF);
buf[1] = (X & 0x0000FF00) >> 8;
buf[2] = (X & 0x00FF0000) >> 16;
buf[3] = (X & 0xFF000000) >> 24;
return buf;
}
там еще это смена позиции начального числа меня в ступор вводит.
если 50 превращается в 32 00 00 00, то 99999999 превращается в FF E0 F5 05
т.е. в первом случае число начинается с 1 байта, а во втором с четвертого. %)
Ну это то, что называется little-endian и big-endian. Порядок байтов должен быть строго оговорен стандартом.
мда мда мда... гляда на то что я напрогал, и ваши несколько строк, понимаю что мне еще учиться и учиться.
Премного благодарен!
Код:
#include <stdio.h>
#include <stdint.h>
union PackInt
{
uint8_t parts[4];
uint32_t data;
};
int main()
{
PackInt a;
a.data = 50;
printf("%02X, %02X, %02X, %02X", a.parts[0], a.parts[1], a.parts[2], a.parts[3]);
return 0;
}
#include <stdint.h>
union PackInt
{
uint8_t parts[4];
uint32_t data;
};
int main()
{
PackInt a;
a.data = 50;
printf("%02X, %02X, %02X, %02X", a.parts[0], a.parts[1], a.parts[2], a.parts[3]);
return 0;
}
Правда тут используется stdint.h, что, возможно, может быть проблемой для старых компиляторов.
Код:
unsigned char *pack_int(int X, unsigned char *buf) {
sprintf(buf, "%c%c%c%c", (X & 0x000000FF), (X & 0x0000FF00) >> 8, (X & 0x00FF0000) >> 16, (X & 0xFF000000) >> 24);
return buf;
}
sprintf(buf, "%c%c%c%c", (X & 0x000000FF), (X & 0x0000FF00) >> 8, (X & 0x00FF0000) >> 16, (X & 0xFF000000) >> 24);
return buf;
}
А для x86 и AMD64 - вообще достаточно записать uint32_t по адресу начала числа
Да, только так, насколько мне сдается, можно получить только big-endian. А вообще, красивое решение. :)
Нет, наоборот. На Intel работает, а насчёт big endian не уверен. В Delphi так вообще описанный Kogrom-ом тип для приведения является штатным, сидит в SysUtils.
Little-endian / big-endian -какая разница. Но IA это не ARM и в нем только little. А насчет юниона - это платформенно зависимое решение, собственно как и раскладка в памяти.
Код:
unsigned char array[44] = {...}; // Ваш массив
int *pointer = (int*)(array + 40); // адрес последних 4-х байт
*pointer = N; // где N - Ваше число
int *pointer = (int*)(array + 40); // адрес последних 4-х байт
*pointer = N; // где N - Ваше число
Число будет "разбито" на байты и размещено в последних 4-х элементах массива в формате little endian на платформе X86.
Цитата:
мне надо туда записывать свои числа... в эти последние 4 байта.
возникает огромное множество проблем, связанных с тем, каким образом разбить число так на байты и записать...
возникает огромное множество проблем, связанных с тем, каким образом разбить число так на байты и записать...
Если надо записывать что-то в последние 4 байта - то и используй memcpy
Ну или можно считать все кроме 4 байтов в поток, а вместо 4 байтов ввести туда свои данные...потом вывести из потока.
Вобщем зависит от конкретных нужд
Если нужен вариант Kogrom, но старый компилятор - то можно соорудить примерно такой велосипед:
Код:
#include <stdio.h>
union Int {
unsigned long int data;
struct {
unsigned char
p1 :8,
p2 :8,
p3 :8,
p4 :8;
} bt;
};
int main( ) {
Int a;
a .data = 50;
printf("%02X, %02X, %02X, %02X", a .bt .p1, a .bt .p2, a .bt .p3, a .bt .p4);
return 0;
}
union Int {
unsigned long int data;
struct {
unsigned char
p1 :8,
p2 :8,
p3 :8,
p4 :8;
} bt;
};
int main( ) {
Int a;
a .data = 50;
printf("%02X, %02X, %02X, %02X", a .bt .p1, a .bt .p2, a .bt .p3, a .bt .p4);
return 0;
}