我想编码和解码可执行文件
问题是关于NULL
文件内容为MZ(NULL),因此二进制代码为
01001101 01011010 00000000
输出应该是:
4d (for M -> 0100 1101)
5a(for Z -> 0101 1010) and
00(for NULL -> 0000 0000)
十六进制:
346435610000
但它是:346435613930
这是我的代码:
CHAR* WriteBuffer = NULL;
BYTE *ReadBuffer = NULL;
DWORD fSize = 0;
OVERLAPPED ol = {0};
BYTE AsciiTable[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
int a = 0;
//...
ReadFile(hndlRead, *ReadBuffer, *fSize, NULL, &ol);
for(DWORD i=0; i< fSize; i++)
{
a = ReadBuffer[i]& 0xf0;
if (a > 15)
{
a = a / 16;
}
wsprintfA(WriteBuffer, "%s%x", WriteBuffer, AsciiTable[a]);
a = ReadBuffer[i] & 0x0f;
wsprintfA(WriteBuffer, "%s%x", WriteBuffer, AsciiTable[a]);
}
编辑/解码:
我希望使用AsciiTable进行解码,但我无法以这种形式进行解码:
//....
int a = 0;
for(DWORD i=0; i<dwFileSize; i++)
{
sscanf_s((CHAR*)ReadBuffer + i*2 ,"%02x" , &a);
wsprintfA(szWriteBuffer, "%s%c", szWriteBuffer, a);
}
答案 0 :(得分:1)
我假设您在写入WriteBuffer之前分配了足够的缓冲区并清除它。
性能问题:你的算法是O(n ^ 2),最好用这个,是O(n):
CHAR AsciiTable[] = '0123456789ABCDEF';
DWORD j=0;
for(DWORD i=0; i< fSize; i++)
{
WriteBuffer[j++]=AsciiTable[ReadBuffer[i]>>4];
WriteBuffer[j++]=AsciiTable[ReadBuffer[i]&0x0f];
}
更新
抱歉,我误解了你的问题。您希望将NULL值(字节值0)解码为恰好2个连续的0的值。在这种情况下,试试这个:
DWORD j=0;
for(DWORD i=0; i< fSize; i++)
{
if (ReadBuffer[i])
{
WriteBuffer[j++]=AsciiTable[ReadBuffer[i]>>4];
WriteBuffer[j++]=AsciiTable[ReadBuffer[i]&0x0f];
}
else
{
WriteBuffer[j++]=WriteBuffer[j++]=0;
}
}
更新II:解码器代码
根据要求,这是O(n)中的解码代码,而不是写入的O(n ^ 2)版本。
#define ASCII2BYTE(V) (((V)>'9')?(V)-'A':(V-'9')
for (DWORD i=0;i<dwFileSize;i+=2)
{
szWriteBuffer[i>>1]=(ASCII2BYTE(ReadBuffer[i])<<4)+ASCII2BYTE(ReadBuffer[i+1]);
}
更新III:如何使用ASCII2BYTE宏(根据要求)
要转换4D5A,请尝试使用ReadBuffer =&#34; 4D5A&#34;,dwFileSize = 4执行解码代码;取出每对字符,然后第一个是最高位半字节(= 4位)并从ASCII转换为十进制(&#39; 4&#39; - > 4),而不是第二个字符&#39 ; d&#39;转换为最低有效半字节(&#39; D&#39; - > 12),而不是(4 <4)+12 = 76,这正是&#39; M&#的ascii代码39 ;.同样适用于5A