我有以下Oracle PLSQL函数,它将ascii字符串转换为数字:
function str2num
(
p_string in varchar2
) return number is
l_i number(15);
l_c number(15);
l_answer number(38);
begin
l_answer := 0;
for l_i in 1..length(p_string) loop
l_c := ascii(substr(p_string, l_i, 1));
l_answer := l_answer + (l_c * power(2, (l_i - 1) * 8));
end loop;
return l_answer;
end str2num;
我想写一个函数将该数字转换回字符串。
基本上,该函数将字符转换为ascii代码,然后通过乘以2^(char_pos-1)*8
将二进制值左移。
所以字符串' Ace'将编码如下:
Chr Ascii Pos Pos - 1 Value Binary Value
A 65 1 0 65 00000000000000001000001
c 99 2 1 25344 00000000110001100000000
e 101 3 2 6619136 11001010000000000000000
final sum = 6644545 11001010110001101000001
我该如何做相反的功能?
答案 0 :(得分:2)
FUNCTION str2num( p_str IN VARCHAR2 ) RETURN NUMBER
IS
p_num NUMBER(38,0) := 0;
BEGIN
FOR i IN REVERSE 1 .. LEAST( LENGTH( p_str ), 15 )
LOOP -- A NUMBER(38,0) can only fit 15 characters.
p_num := p_num + ASCII( SUBSTR( p_str, i, 1 ) ) * POWER( 256, i - 1 );
END LOOP;
RETURN p_num;
END str2num;
FUNCTION num2str( p_num IN NUMBER ) RETURN VARCHAR2
IS
p_str VARCHAR2(15); -- A NUMBER(38,0) can only fit 15 characters.
p_var NUMBER(38,0) := p_num;
BEGIN
WHILE p_var > 0 LOOP
p_str := p_str || CHR( MOD( p_var, 256 ) );
p_var := FLOOR( p_var / 256 );
END LOOP;
RETURN p_str;
END num2str;
答案 1 :(得分:0)
完美"练习"用于递归函数!
你还需要写一些错误处理;并且,由于number
数据类型是有限的,最好转换为二进制(而不是十进制)数字,并将二进制数写为字符串而不是真数,所以你没有限制长度。 (如果需要,使用CLOB。)但这是一个不同的问题。
<强> str2num 强>
create or replace function str2num
(
p_string in varchar2
) return number is
begin
return ascii(substr(p_string, 1, 1))
+ case when length(p_string) = 1 then 0
else 256 * str2num(substr(p_string, 2)) end;
end str2num;
/
select str2num('Ace') from dual;
STR2NUM('ACE')
--------------
6644545
num2str
create or replace function num2str
(
p_number in number
) return varchar2 is
begin
return chr(mod(p_number, 256))
|| case when p_number >= 256 then num2str(trunc(p_number/256)) end;
end num2str;
/
select num2str(6644545) from dual;
NUM2STR(6644545)
----------------
Ace