PL / SQL校验位,使用MOD 11的luhn

时间:2015-12-09 03:09:55

标签: oracle plsql luhn

所以这是一个问题: 编写代码以获取ID并确定校验位是否正确

更新后的代码:

    Set SERVEROUTPUT ON
 DECLARE
      val_num NUMBER := '&user_input';
      holder NUMBER := 0;
      y NUMBER := 0;
      conv_string VARCHAR2(20);
   BEGIN
     conv_string := to_char(val_num*10);
     for x in 1..length(conv_string) loop
       y := to_number(substr(conv_string, -x, 1));
       if mod(x,2) = 0 then
         y := y * 2;
        if y > 9 then
         y := y - 9;
        end if;
       end if;
      holder := holder + y;
    end loop;
    dbms_output.put_line ('Check is '||(11-Mod(holder, 11)));
 END luhn;
   /
 SET SERVEROUTPUT ON

回报是:

SQL> @ loop
Enter value for user_input: 036532
old   2:       val_num NUMBER := '&user_input';
new   2:       val_num NUMBER := '036532';
Check is 2

应该是6

2 个答案:

答案 0 :(得分:3)

实际执行前

SET SERVEROUTPUT ON

启用SQL * Plus以获取数据库输出缓冲区。

以下是解决方案:https://community.oracle.com/thread/837639?start=0&tstart=0

答案 1 :(得分:0)

luhn算法有很多不同的变体,所以在评论中查看这些实现和你的(我认为不完整的)描述我认为这可能与你正在寻找的相当接近,并给出正确的校验和036532根据您的初步问题。

希望它有用

Set SERVEROUTPUT ON
 DECLARE
      val_num number := '036532';
      holder NUMBER := 0;
      y NUMBER := 0;
      conv_string VARCHAR2(20);
   BEGIN
     conv_string := to_char(val_num);
     FOR X IN 1..LENGTH(CONV_STRING) LOOP
       Y := TO_NUMBER(SUBSTR(CONV_STRING, -X, 1));
       IF ((X+1) > 10) THEN 
          Y := Y * 10;
       ELSE
          Y := Y * (X + 1);
       END IF;
       IF (Y >= 10) THEN 
          HOLDER := HOLDER + TO_NUMBER(substr(TO_CHAR(Y), 1, 1)) +  TO_NUMBER(substr(TO_CHAR(Y), 2, 1));
       ELSE
          HOLDER := HOLDER + Y;
       END IF;
     END LOOP;

         HOLDER :=  MOD(HOLDER, 11);
         Holder := 11 - mod(holder, 11);
     dbms_output.put_line ('Check is '|| holder);
 END luhn;
   /
 SET SERVEROUTPUT ON