create or replace function CalcMac(p_str in varchar2) return varchar2
is
type arr_num is table of number(5) index by binary_integer;
type arr_char is table of char(2) index by binary_integer;
s_arr arr_char;
Mac arr_num;
Len number;
Groupnum number;
i number;
s_str varchar2(4000);
result varchar2(4000);
function fn_and(p_number1 int, p_number2 int) return integer is
result integer;
begin
result := bitand(p_number1, p_number2);
return result;
end fn_and; function fn_or(p_number1 int, p_number2 int) return integer is
result integer;
begin
result := p_number1 - bitand(p_number1, p_number2) + p_number2;
return result;
end fn_or; function fn_xor(p_number1 int, p_number2 int) return integer is
result integer;
begin
result := (p_number1 - bitand(p_number1, p_number2)) + (p_number2 - bitand(p_number1, p_number2));
return result;
end fn_xor;
begin
Len := lengthb(p_str);
Groupnum := trunc(Len / 4);
if (Len mod 4) <> 0 then
Groupnum := Groupnum + 1;
end if; Mac(1) := 0;
Mac(2) := 0;
Mac(3) := 0;
Mac(4) := 0; --转换为16进制
for i in 1..length(p_str) loop
s_str := s_str || trim(to_char(ascii(substr(p_str, i, 1)), 'xxxx'));
end loop;
for i in 1..length(s_str)/2 loop
s_arr(i) := substr(s_str, 1, 2);
s_str := substr(s_str, 3, length(s_str));
end loop;
for i in 1..Groupnum loop
if (i - 1) * 4 + 1 <= Len then
Mac(1) := fn_xor(Mac(1), to_number(s_arr((i - 1) * 4 + 1), 'xxx'));
end if;
if (i - 1) * 4 + 2 <= Len then
Mac(2) := fn_xor(Mac(2), to_number(s_arr((i - 1) * 4 + 2), 'xxx'));
end if;
if (i - 1) * 4 + 3 <= Len then
Mac(3) := fn_xor(Mac(3), to_number(s_arr((i - 1) * 4 + 3), 'xxx'));
end if;
if (i - 1) * 4 + 4 <= Len then
Mac(4) := fn_xor(Mac(4), to_number(s_arr((i - 1) * 4 + 4), 'xxx'));
end if;
end loop;
result := '';
result := result||chr(trunc(mac(1)/16) + 48);
result := result||chr(fn_and(mac(1), 15) + 48);
result := result||chr(trunc(mac(2)/16) + 48);
result := result||chr(fn_and(mac(2), 15) + 48);
result := result||chr(trunc(mac(3)/16) + 48);
result := result||chr(fn_and(mac(3), 15) + 48);
result := result||chr(trunc(mac(4)/16) + 48);
result := result||chr(fn_and(mac(4), 15) + 48);
return result;
end CalcMac;
能否改进一下,这个是我初步写的,对数据包进行MAC校验的
各位高手帮忙改进一下,谢谢!
is
type arr_num is table of number(5) index by binary_integer;
type arr_char is table of char(2) index by binary_integer;
s_arr arr_char;
Mac arr_num;
Len number;
Groupnum number;
i number;
s_str varchar2(4000);
result varchar2(4000);
function fn_and(p_number1 int, p_number2 int) return integer is
result integer;
begin
result := bitand(p_number1, p_number2);
return result;
end fn_and; function fn_or(p_number1 int, p_number2 int) return integer is
result integer;
begin
result := p_number1 - bitand(p_number1, p_number2) + p_number2;
return result;
end fn_or; function fn_xor(p_number1 int, p_number2 int) return integer is
result integer;
begin
result := (p_number1 - bitand(p_number1, p_number2)) + (p_number2 - bitand(p_number1, p_number2));
return result;
end fn_xor;
begin
Len := lengthb(p_str);
Groupnum := trunc(Len / 4);
if (Len mod 4) <> 0 then
Groupnum := Groupnum + 1;
end if; Mac(1) := 0;
Mac(2) := 0;
Mac(3) := 0;
Mac(4) := 0; --转换为16进制
for i in 1..length(p_str) loop
s_str := s_str || trim(to_char(ascii(substr(p_str, i, 1)), 'xxxx'));
end loop;
for i in 1..length(s_str)/2 loop
s_arr(i) := substr(s_str, 1, 2);
s_str := substr(s_str, 3, length(s_str));
end loop;
for i in 1..Groupnum loop
if (i - 1) * 4 + 1 <= Len then
Mac(1) := fn_xor(Mac(1), to_number(s_arr((i - 1) * 4 + 1), 'xxx'));
end if;
if (i - 1) * 4 + 2 <= Len then
Mac(2) := fn_xor(Mac(2), to_number(s_arr((i - 1) * 4 + 2), 'xxx'));
end if;
if (i - 1) * 4 + 3 <= Len then
Mac(3) := fn_xor(Mac(3), to_number(s_arr((i - 1) * 4 + 3), 'xxx'));
end if;
if (i - 1) * 4 + 4 <= Len then
Mac(4) := fn_xor(Mac(4), to_number(s_arr((i - 1) * 4 + 4), 'xxx'));
end if;
end loop;
result := '';
result := result||chr(trunc(mac(1)/16) + 48);
result := result||chr(fn_and(mac(1), 15) + 48);
result := result||chr(trunc(mac(2)/16) + 48);
result := result||chr(fn_and(mac(2), 15) + 48);
result := result||chr(trunc(mac(3)/16) + 48);
result := result||chr(fn_and(mac(3), 15) + 48);
result := result||chr(trunc(mac(4)/16) + 48);
result := result||chr(fn_and(mac(4), 15) + 48);
return result;
end CalcMac;
能否改进一下,这个是我初步写的,对数据包进行MAC校验的
各位高手帮忙改进一下,谢谢!
s_arr(i) := substr(s_str, 1, 2);
s_str := substr(s_str, 3, length(s_str));
end loop; ----->
for i in 1..length(s_str)/2 loop
s_arr(i) := substr(s_str, 2*i - 1, 2);