A
app2001
Unregistered / Unconfirmed
GUEST, unregistred user!
最近在搞一个进制转换的函数,弄来弄去转不出弯来,哪位有识之士帮帮忙????
事情是这样的,我手上有一个VC的源码,是一个DLL中的函数,本意是想自己仿一个出来调用方便些,不用每次都为了这个功能调用那个DLL了.函数如下:
__int16 __stdcall hex_asc(unsigned char *hex,unsigned char *asc,long length)
{
UCHAR hLowbit,hHighbit;
long i;
for(i=0;i<length*2;i=i+2)
{
hLowbit=hex[i/2]&0x0f;
hHighbit=hex[i/2]/16;
if(hHighbit>=10)
asc=hHighbit+'7';
else
asc=hHighbit+'0';
if(hLowbit>=10)
asc[i+1]=hLowbit+'7';
else
asc[i+1]=hLowbit+'0';
}
asc[length*2]='/0';
return 0;
}
我想仿一个一样的D版函数出来
function hex_asc1(hex, asc: PCHAR
len: LongInt): Integer;
var
hLowbit, hHighbit : Byte;
i : LongInt;
begin
i := 0;
while i < len * 2 do
begin
hLowbit := Integer(hex[i div 2]) and $F;
hHighbit := Integer(hex[i div 2]) div 16;
if hHighbit >= 10 then
asc := Char(hHighbit + Byte(#37))
else
asc := Char(hHighbit + Byte(#30));
if hLowbit >= 10 then
asc[i + 1] := Char(hLowbit + Byte(37))
else
asc[i + 1] := Char(hLowbit + Byte(30));
i:=i+2;
end;
asc[len * 2] := #0;
end;
但在实际调用中,发现我调用这个仿制出来的函数所得到的结果和调用上述VC函数所得到的结果是不一样的.
调用方式:
GetMem(sasc, 100);
try
hex_asc(pchar(pData),sasc,DLen)
value := sasc+' tt '+StrToAsc(pchar(pData),DLen)
finally
FreeMem(sasc);
end;
正常调用结果应该为:3BFF1100,但我那个仿VC的函数得出来的是:!044&not;&not
然后呢,我又查找资料和请教了一些朋友得到了如下函数:
function hex_asc2 (StrString: string
Len: Integer): string
var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(trim (StrString))
if tempstr = '' then
exit;
for i := 1 to Len do
Result := Result + inttohex(Ord(StrString), 2);
end;
function hex_asc3(src: string
Len: Integer): string;
var
i: Integer;
begin
SetLength(Result, 2 * Len);
for i:= 1 to Len do
begin
Result[i * 2 - 1]:= ByteToChar((Byte(src) and $f0) shr 4);
Result[i * 2]:= ByteToChar(Byte(src) and $0f);
end;
end;
function ByteToChar(N: Byte): Char;
begin
if N in [0..9] then
Result := Chr(48 + N)
else
if N in [10..15] then
Result := Chr(55 + N)
else
Result := Chr(255);
end;
这两个函数呢,在一定的情况下,调用后得到的结果和DLL中是一样的,但也不完全是一样的,又回到刚才那个调用情况:
GetMem(sasc, 100);
try
hex_asc(pchar(pData), sasc, SizeOf(pData));
value := sasc+' '+ hex_asc2(pchar(pData)) +' '+ hex_asc3(pchar(pData));
finally
FreeMem(sasc);
end;
这么调用得到的三个结果是
复位应答字节串: 3BFF1100 3BFF11 3BFF11
第一个是DLL中调用得回的正确结果
后面两个函数则得不到最后两个零
最后请教了朋友,改进如下:
function hex_asc2(StrString: PChar
Len: Integer): string;
var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(string(StrString))
if tempstr = '' then
exit;
for i := 0 to Len - 1 do
Result := Result + inttohex(Ord(StrString), 2);
end;
function hex_asc3 (src: PChar
Len: Integer): string;
var
i : integer;
begin
SetLength(Result, 2 * Len);
for i := 0 to Len - 1 do
begin
Result[i * 2 + 1] := ByteToChar((Byte(src^) and $F0) shr 4);
Result[i * 2 + 2] := ByteToChar(Byte(src^) and $0F);
Inc(src);
end;
end;
这样才得到和DLL中的VC函数一样的正确结果出来,结果虽然是完成了,但我还很是糊涂,想请各位有识之士给我好好总结一下.
1、 为什么我仿VC的那个函数hex_as1得不到正确结果,是哪一步没有转换过来时正确呢?
2、 为什么hex_asc2和hex_asc3在参数为String时,转换回来的结果不完全正确,换为Pchar类型后就正常了呢?
3、 hex_asc2和hex_asc3实现的方式不是很相同,但结果是一样的,这两个函数的实现原理是什么样的呢,烦请解释?
最后我还有一个再反转换回去的VC函数
这题单独另开贴给200分,烦请再给做一个能达到同样功能的D版函数
__int16 __stdcall asc_hex(unsigned char *asc, unsigned char *hex, long pair_len)
{
char src1,src2;
int len;
for (len=0
len < pair_len
len++)
{
src1 = *(asc+len*2);
src2 = *(asc+len*2+1);
if ((src1>='0') &&
(src1<='9'))
src1=src1-'0';
else if ((src1>='A') &&
(src1<='F'))
src1=src1-'A'+10;
else if ((src1>='a') &&
(src1<='f'))
src1=src1-'a'+10;
else
return -1;
if ((src2>='0') &&
(src2<='9'))
src2=src2-'0';
else if ((src2>='A') &&
(src2<='F'))
src2=src2-'A'+10;
else if ((src2>='a') &&
(src2<='f'))
src2=src2-'a'+10;
else
return -1;
*hex++ = (src1 << 4) | src2
}
return 0;
}
事情是这样的,我手上有一个VC的源码,是一个DLL中的函数,本意是想自己仿一个出来调用方便些,不用每次都为了这个功能调用那个DLL了.函数如下:
__int16 __stdcall hex_asc(unsigned char *hex,unsigned char *asc,long length)
{
UCHAR hLowbit,hHighbit;
long i;
for(i=0;i<length*2;i=i+2)
{
hLowbit=hex[i/2]&0x0f;
hHighbit=hex[i/2]/16;
if(hHighbit>=10)
asc=hHighbit+'7';
else
asc=hHighbit+'0';
if(hLowbit>=10)
asc[i+1]=hLowbit+'7';
else
asc[i+1]=hLowbit+'0';
}
asc[length*2]='/0';
return 0;
}
我想仿一个一样的D版函数出来
function hex_asc1(hex, asc: PCHAR
len: LongInt): Integer;
var
hLowbit, hHighbit : Byte;
i : LongInt;
begin
i := 0;
while i < len * 2 do
begin
hLowbit := Integer(hex[i div 2]) and $F;
hHighbit := Integer(hex[i div 2]) div 16;
if hHighbit >= 10 then
asc := Char(hHighbit + Byte(#37))
else
asc := Char(hHighbit + Byte(#30));
if hLowbit >= 10 then
asc[i + 1] := Char(hLowbit + Byte(37))
else
asc[i + 1] := Char(hLowbit + Byte(30));
i:=i+2;
end;
asc[len * 2] := #0;
end;
但在实际调用中,发现我调用这个仿制出来的函数所得到的结果和调用上述VC函数所得到的结果是不一样的.
调用方式:
GetMem(sasc, 100);
try
hex_asc(pchar(pData),sasc,DLen)
value := sasc+' tt '+StrToAsc(pchar(pData),DLen)
finally
FreeMem(sasc);
end;
正常调用结果应该为:3BFF1100,但我那个仿VC的函数得出来的是:!044&not;&not
然后呢,我又查找资料和请教了一些朋友得到了如下函数:
function hex_asc2 (StrString: string
Len: Integer): string
var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(trim (StrString))
if tempstr = '' then
exit;
for i := 1 to Len do
Result := Result + inttohex(Ord(StrString), 2);
end;
function hex_asc3(src: string
Len: Integer): string;
var
i: Integer;
begin
SetLength(Result, 2 * Len);
for i:= 1 to Len do
begin
Result[i * 2 - 1]:= ByteToChar((Byte(src) and $f0) shr 4);
Result[i * 2]:= ByteToChar(Byte(src) and $0f);
end;
end;
function ByteToChar(N: Byte): Char;
begin
if N in [0..9] then
Result := Chr(48 + N)
else
if N in [10..15] then
Result := Chr(55 + N)
else
Result := Chr(255);
end;
这两个函数呢,在一定的情况下,调用后得到的结果和DLL中是一样的,但也不完全是一样的,又回到刚才那个调用情况:
GetMem(sasc, 100);
try
hex_asc(pchar(pData), sasc, SizeOf(pData));
value := sasc+' '+ hex_asc2(pchar(pData)) +' '+ hex_asc3(pchar(pData));
finally
FreeMem(sasc);
end;
这么调用得到的三个结果是
复位应答字节串: 3BFF1100 3BFF11 3BFF11
第一个是DLL中调用得回的正确结果
后面两个函数则得不到最后两个零
最后请教了朋友,改进如下:
function hex_asc2(StrString: PChar
Len: Integer): string;
var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(string(StrString))
if tempstr = '' then
exit;
for i := 0 to Len - 1 do
Result := Result + inttohex(Ord(StrString), 2);
end;
function hex_asc3 (src: PChar
Len: Integer): string;
var
i : integer;
begin
SetLength(Result, 2 * Len);
for i := 0 to Len - 1 do
begin
Result[i * 2 + 1] := ByteToChar((Byte(src^) and $F0) shr 4);
Result[i * 2 + 2] := ByteToChar(Byte(src^) and $0F);
Inc(src);
end;
end;
这样才得到和DLL中的VC函数一样的正确结果出来,结果虽然是完成了,但我还很是糊涂,想请各位有识之士给我好好总结一下.
1、 为什么我仿VC的那个函数hex_as1得不到正确结果,是哪一步没有转换过来时正确呢?
2、 为什么hex_asc2和hex_asc3在参数为String时,转换回来的结果不完全正确,换为Pchar类型后就正常了呢?
3、 hex_asc2和hex_asc3实现的方式不是很相同,但结果是一样的,这两个函数的实现原理是什么样的呢,烦请解释?
最后我还有一个再反转换回去的VC函数
这题单独另开贴给200分,烦请再给做一个能达到同样功能的D版函数
__int16 __stdcall asc_hex(unsigned char *asc, unsigned char *hex, long pair_len)
{
char src1,src2;
int len;
for (len=0
len < pair_len
len++)
{
src1 = *(asc+len*2);
src2 = *(asc+len*2+1);
if ((src1>='0') &&
(src1<='9'))
src1=src1-'0';
else if ((src1>='A') &&
(src1<='F'))
src1=src1-'A'+10;
else if ((src1>='a') &&
(src1<='f'))
src1=src1-'a'+10;
else
return -1;
if ((src2>='0') &&
(src2<='9'))
src2=src2-'0';
else if ((src2>='A') &&
(src2<='F'))
src2=src2-'A'+10;
else if ((src2>='a') &&
(src2<='f'))
src2=src2-'a'+10;
else
return -1;
*hex++ = (src1 << 4) | src2
}
return 0;
}