[펌] PHP로 된 RSS 리더 소스

<html>
<head>
<title>SAX Demonstration</title>
<META HTTP-EQUIV=’Content-type’ CONTENT=’text/html; charset=euc-kr’>
</head>
<body>
<h1>RSS 리더기</h1>

<?php

$file = “http://blog.naver.com/post/postXMLList.jsp?blogId=suvisor”;

$currentTag = “”;
$currentAttribs = “”;

function startElement($parser, $name, $attribs)
{
global $currentTag, $currentAttribs;
$currentTag = $name;

$currentAttribs = $attribs;
switch ($name) {

default:
echo(“startElement : $name<br>”);
break;
}
}

function endElement($parser, $name)
{
global $currentTag;
switch ($name) {
default:
echo(“<br>$name endElement<br>”);
break;
}
$currentTag = “”;
$currentAttribs = “”;
}

function characterData($parser, $data)
{
global $currentTag;
switch ($currentTag) {
case “link”:
echo(“<a href=”$data”>$data</a>n”);
break;
case “title”:
echo(“title : $data”);
break;
default:
echo($data);
break;
}
}

$xmlParser = xml_parser_create();

$caseFold = xml_parser_get_option($xmlParser,
XML_OPTION_CASE_FOLDING);

$targetEncoding = xml_parser_get_option($xmlParser,
XML_OPTION_TARGET_ENCODING);

if ($caseFold == 1) {
xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, false);
}

xml_set_element_handler($xmlParser, “startElement”, “endElement”);
xml_set_character_data_handler($xmlParser, “characterData”);

if (!($fp = fopen($file, “r”))) {
die(“Cannot open XML data file: $file”);
}

while ($data = fread($fp, 4096)) {
if (!xml_parse($xmlParser, $data, feof($fp))) {
die(sprintf(“XML error: %s at line %d”,
xml_error_string(xml_get_error_code($xmlParser)),
xml_get_current_line_number($xmlParser)));
xml_parser_free($xmlParser);
}
}
xml_parser_free($xmlParser);
?>
</table>
</body>
</html>

간단강좌 : 파티션

하드디스크는 몇 개의 파티션(partitions)으로 나누어지며, 각 파티션은 서로 독립적으로 동작한다. 하나의 디스크에서 두 운영체제를 사용할 때에도 파티션을 이용하여 서로 문제를 일으키지 않고 사용할 수 있다.

 

리눅스에서는 어떤 파티션이 필요한가

 

불행히도 많은 운영체제에서 논리 파티션에서 부팅하는 것을 결사적으로 막고 있는 관계로, 리눅스 외의 다른 운영체제를 사용해야 한다면 한 개의 하드디스크에서 최대 4개까지 만들 수 있는 프라이머리 파티션 중 최소 하나는 쓸 수 없다는 결론이 나올 것이다. 또한 확장 파티션을 만들기 위해서는 또 하나의 프라이머리 파티션을 희생해야 한다. 확장 파티션은 나머지 디스크 공간을 논리 파티션으로 나누어 쓰기 위해 꼭 필요하다.

 

리눅스 시스템에는 스왑 공간도 필요하다. 대개의 경우 스왑 파티션을 따로 설정하여 스왑을 만들며, 이 파티션은 어디에 있어도 상관없으므로 논리 파티션에 설치하도록 하겠다. 리눅스 스왑 전용 파티션은 0x82 “Linux swap” 형식으로 포맷한다. 일반적인 리눅스 파티션을 0x83 “Linux Native” 형식으로 포맷하는 것과 비교된다.

 

물론 리눅스를 설치하기 위해서는 스왑을 제외하고 단 한 개의 파티션만 있어도 충분할지 모른다. 그러나 부트 이미지와 응용 프로그램, 홈 디렉토리, 설정 파일, 계속 변경되는 공유 데이터 등은 서로 다른 파티션에 저장하는 것이 안전하므로 각각 나누어준다.

 

데이터 블록과 파일 저장

 

운영 체제는 디스크 공간을 블록 단위로 관리한다. 파일의 크기가 블록의 크기에 딱 맞는 일은 거의 없으므로, 파일이 저장된 마지막 블록의 일부는 평균적으로 블록 반 개의 크기만큼 낭비되는 법이다.

 

파일 데이터가 서로 인접한 블록에 저장될수록 접근 속도는 빨라진다. 리눅스 시스템에서는 점점 커지는 파일을 위해 8 개의 인접 블록을 한 단위로 하여 공간을 미리 배분해 놓았다. 사용되지 않은 사전 할당 공간은 파일이 닫혀질 때 놓여나므로, 그 이상의 공간 낭비는 일어나지 않는다. 한 파일을 구성하는 블록이 각각 멀리 떨어져 있다면, 디스크가 일일이 헤드를 움직여야 하고 운영 체제의 접근이 늘어나는 등 많은 불합리한 일이 생긴다. 리눅스 시스템에서는 이런 일을 막기 위해 몇 가지 전략을 사용하므로 스풀 디렉토리와 같은 자주 읽고 쓰여지며 수시로 삭제되고 새로운 데이터가 들어오는 파티션도 큰 문제를 일으키지 않는 다. 정상적으로 사용한다면 리눅스 본래의 파일 시스템에서는 굳이 디스크를 정리하지 않아도 된다. 대개 한 파티션에 5% 정도의 공간만 있다면 리눅스에서 적절히 관리해 줄 것이다.

 

MBR

 

하드디스크가 어떻게 나누어져 있는가에 대한 정보는 하드디스크의 첫 번째 섹터에 저장된다(즉 첫 번째 디스크 표면 위에 있는 첫 번째 트랙의 첫 번째 섹터). 이 첫 번째 섹터가 바로 master boot record (MBR)이다. MBR은 컴퓨터가 처음 부팅할 때 바이오스가 읽어들여 부트 이미지를 불러들이는 작은 프로그램을 실행하는 섹터이다. 이와 같은 작은 프로그램을 부트 로더라 하며, 바이오스가 한 번에 읽어 들일 수 있는 크기는 정해져 있는 데 비해 부팅을 위한 프로그램의 크기는 계속 커지고 있어, 부트 프로그램을 불러들이기 위해 사용된다.

 

파티션을 구별하는 방법은?

파티션을 구별할 때는 드라이브의 순서와 파티션이 있는 순서를 차례로 읽어 나가면 된다. 지금부터는 각 드라이브에 있는 파티션의 이름을 짓는 방법을 설명할 것이다.

 

IDE 방식을 사용하는 경우 하나의 IDE 케이블에는 두 개의 드라이브를 설치할 수 있고 시스템에는 두 개의 IDE 케이블을 사용할 수 있다. 그러므로 최대 4개의 IDE 하드디스크를 설치할 수 있다. 이때 첫 번째 케이블의 가운데 설치되는 드라이브가 프라이머리 마스터 드라이브이고 이 드라이브가 1번 드라이브이다. 그리고 컷번째 케이블의 끝에 설치되는 드라이브가 2번째 드라이브이고 프라이머리 슬레이브 드라이브라고 한다. 세 번째 드라이브는 두 번째 케이블의 가운데 설치되는 드라이브이다. 마지막 네 번째 드라이브는 두 번째 케이블의 끝에 설치되는 드라이브이다. 요즘은 EIDE를 사용하고 있기에 마스터와 슬레이브의 결정은 점퍼에 의해 결정되기 때문에 방금 설명한 것이 정확히 맞지 않는다. 일부 IDE 케이블에는 케이블에 마스터와 슬레이브가 적혀있는 것이 있다. 이 경우는 이에 맞추어 연결하지 않으면 사용할 수 없게 된다.

 

드라이브의 이름은 그 순서대로 hda, hdb, hdc, hdd로 정해진다.

 

파티션의 이름은 각 드라이브의 파티션 순서에 따라 번호가 주어지고 파티션의 형식은 무시된다. 예를 들어 첫 번째 프라이머리 파티션은 1을 갖게 되고 두 번째 확장 파티션은 2번, 세 번째 프라이머리 파티션은 3번을 갖게 된다. 대부분 관리의 편리성을 위해 같은 종류의 파티션을 묶어 놓는다. 그래서 1번부터 3번까지는 프라이머리 파티션, 4번은 확장 파티션, 5번 이후는 논리 파티션으로 지정된다. 파티션을 4개만 사용하는 경우 모두 프라이머리 파티션으로 지정된다. 파티션의 장치이름은 드라이브이름뒤에 파티션번호를 붙이면 된다. 예를 들어 세 번째 드라이브의 첫 번째 논리 파티션인 경우 hdc5가 된다. IDE 드라이브이므로 hd로 지정되고 3번째 드라이브이므로 알파벳 3번째 글자인 c, 첫 번째 논리 파티션이므로 5가 선택되어 hdc5인 것이다. 3,4파티션이 모두 확장파티션인 경우 3번 확장 파티션의 첫 번째 논리 파티션이 5번이 되고 3번 파티션의 마지막 논리 파티션의 번호+1이 4번째 확장 파티션의 첫 번째 논리 파티션의 번호가 된다.

 

SCSI 하드디스크의 경우는 SCSI ID에 의해 그 순서가 정해지고 이름을 붙이는 방법은 동일하다. 단지 SCSI 하드라는 것을 의미하기 위해 hd대신에 sd를 사용한다. 세 번째 하드디스크의 첫 번째 파티션은 sdc1이 된다.

리눅스 기본 환경변수

리눅스는 원래 개인사용을 목적에 둔 것이 아니고 여러 사용자가 동시에 사용할 수 있도록 하기 위해 만들어진 것이다. 그래서 각 사용자 별로 다른 환경을 만들기 위해 여러 가지 설정을 저장하는 공간이 필요했다. 그 공간중의 하나가 환경변수이고 아래의 목록은 한컴리눅스 2.2에서 root로 로그인한 상태의 환경변수들이다. 환경변수를 확인하려면 다음과 같이 입력한다.

 

# env

 

그러면 상당히 많은 환경변수를 볼 수 있을 것이다. 이제 이 중에서 꼭 알아 두어야 하는 변수에 대해 구체적으로 확인해 보자.

 

SHELL=/bin/bash

 

이 환경변수는 지금 사용하고 있는 셸이 어떤 것인지를 전체 경로로 보여준다. 지금은 BASH를 사용하고 있다고 알려주고 있다.

 

HISTFILE=/root/.bash_history

 

이 파일은 최근에 사용한 명령들을 가지고 있는 파일이 /root/.bash_history 라는 것을 알려준다.

 

HISTFILESIZE=1000, HISTSIZE=1000

 

이 두 변수는 같은 역할을 담당하고 최근 명령을 저장하는 파일의 최대 크기를 1KB로 한다고 설정한다.

 

LANG=ko_KR.euckr, LC_ALL=ko_KR.euckr

 

이 두 변수는 현재 한글 환경을 사용한다고 정의한 것이다. LANG대신 LC_ALL으로 설정하는 것을 추천한다. 영문 환경은 LC_ALL=C이다.

 

MAIL=/var/spool/mail/root

 

메일박스의 위치를 지정한다.

 

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin

 

프로그램을 찾는 순서를 지정한다. 각 디렉토리가 :(COLON)으로 구별되어 있다. 지금 이 부분의 예는 root로 로그인 했을 때의 것이다. 일반 사용자라면 sbin 쪽의 디렉토리는 기본 PATH로 잡히지 않는다.

 

PS1=$'[u@h W]$ ‘

이 변수는 프롬프트의 모습을 설정하는 것으로 지금처럼 설정되어 있는 경우

 

[root@linux1 etc]#

 

와 같이 사용한다. u는 사용자계정, h는 호스트이름, W는 현재 디렉토리를 뜻한다. 전체 경로는 w를 사용한다.

 

TERM=vt100

 

현재 사용중인 터미널 형식이 vt100이라는 것을 알려준다. vt100은 여러 환경에서 잘 호환되지만 시대에 뒤떨어진 면이 없지 않으며, 요즘은 많은 곳에서 xterm을 기본 터미널로 사용하는 추세이다.

 

 

 

 

 

사용자가 변경가능한 환경변수는 다음과 같다.

  • IFS=$’ tn’
  • LANG=ko_KR.euckr
  • LC_ALL=ko_KR.euckr
  • MAILCHECK=60
  • PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
  • PS1=$'[u@h W]$ ‘
  • PS2=$’> ‘
  • PS4=$’+ ‘
  • TERM=vt100
  • XMODIFIERS=@im=Ami

 

BASH를 사용하는 경우 이 환경변수를 변경할 때는 “변수명=값” 으로 변경한다. 예를 들어 현재 프롬프트를 [root:/usr/bin]# 으로 표시하게 바꾸고 싶다면

 

PS1=$'[u:w]$’

 

와 같이 입력한다.

리눅스에서 백업하기 – tar와 테이프를 이용한 백업

정기적으로 백업을 수행하는 것은 시스템의 안전을 위해 절대 양보할 수 없는 부분이다. 아무리 안정적인 시스템이라도 언제 위기가 닥칠 지는 아무도 모르는 일인 것이다. 가볍게는 단순한 오류에서부터 침입자의 공격, 심지어는 시스템의 도난까지, 우리가 상상할 수 있는 모든 사고는 운이 나쁘면 얼마든지 일어날 수 있는 일이다. 게다가 사람의 실수로 중요한 파일을 잘못 수정하거나 삭제하는 경우는 비일비재할 것이다. 이럴 때 정기적으로 백업을 해 두었다면 파일 손실의 가능성을 줄이고 복구 가능성을 높일 수 있다.

 

백업을 실행하는 가장 안전한 방법은 테이프, CD-ROM 혹은 원격지 서버에 백업하여 이 시스템에서 백업한 데이터를 분리하여 보관하는 것이다. 그렇지 않다면 최소한 백업을 마치면 백업용 하드디스크의 마운트를 풀어놓고, 백업할 때에만 다시 마운트 하여 사용해야 할 것이다. 물론 이와 같은 작업은 cron을 사용하여 편리하게 진행할 수 있다. 자세한 내용은 셸 프로그래밍을 참고하자.

 

리눅스에는 백업 작업을 위한 많은 프로그램이 있다. dd나 dump, tar, cpio 등을 사용한 방법은 가장 흔한 것들이다. 그 외에도 다양한 텍스트 혹은 GUI 기반의 다양한 유틸리티를 사용하여 편리하게 백업 작업을 할 수 있다. 이와 같은 백업 도구를 사용하기 위해서는 다음과 같은 점을 고려한다.

 

* 이식성이 좋은가? 이 시스템에서 백업한 내용을 조금 다른 환경에서 복구할 수 있는가? 다른 유닉스 시스템이나 다른 종류의 배포판을 사용하는 시스템에서 이 백업 내용을 무리 없이 복구하여 사용할 수 있는가?

* 사용하기 편리한가? 기능이 쉽고 직관적이라 실수를 줄일 수 있는가?

* 원격 백업과 자동 백업을 지원하는가?

 

또한 가격과 안정성, 저장 용량, 전송 속도 등을 감안하여 다양한 매체를 사용할 수 있을 것이다. 일단 여러가지 툴이 있겠지만 가장 기본적인 tar 사용법을 간단히 살펴본다.

 

tar은 유닉스의 전통적인 압축 명령이었다. tar는 그 이름을 보면 알 수 있겠지만 테이프에 저장하기 위해 파일을 묶는 것에서 유래했다. 이런 tar와 테이프를 이용한 백업은 아주 전통적인 방식으로, 현재에는 많이 사용하지 않지만 알아 볼 만한 부분이라고 생각한다.

 

tar의 사용법은 이미 앞에서 다루었으므로 자세히 설명하지 않겠다. 이 부분에서는 테이프를 사용하는 방법을 함께 알아보겠다.

 

테이프 드라이브를 조작하는 명령은 mt라는 명령이 있고 이는 mt-st라는 패키지에 들어 있다. 이 명령은 테이프 드라이브의 테이프를 파일하나 앞/뒤로 이동하거나 테이프의 맨 뒤와 맨 앞으로 이동하는 명령을 줄 수 있다.

 

테이프 드라이브는 환경변수 TAPE로 정의하거나 옵션으로 -f 디바이스 이름 또는 -t 디바이스 이름으로 지정한다.

 

테이프의 끝으로 갈 때에는 fsf 또는 fsfm으로 지정한다. fsfm을 사용하면 어느 정도 감을 것인지를 지정할 수 있다. 처음으로 갈 때에는 bsf와 bsfm을 사용하며, 역시 bsfm을 사용하면 어느 정도 감을 것인지 지정할 수 있다. 테이프를 끝으로 보내거나 처음으로 이동하려고 할 때는 eod 와 rewind를 사용한다. 테이프의 사용을 끝내고 드라이브에서 빼내려고 할 때에는 offline을 사용하고 테이프의 처음으로 감은 뒤에 빼내려면 rewoffl을 사용한다. 더욱 많은 옵션은 man mt 명령으로 확인해 볼 수 있다.

 

tar 명령을 사용해서 테이프로 백업을 하려면 압축파일의 위치를 테이프 드라이브를 위한 디바이스로 지정하면 된다. 예를 들어 /usr/local/ 드라이브를 백업할 때에는 다음과 같이 입력한다.

 

# tar cvf /dev/tape /usr/local

 

tar 명령을 사용해서 백업한 파일을 복구할 때에는 이렇게 한다.

 

# tar xvf /dev/tape

 

이 명령을 실행하면 테이프에 압축된 모든 파일의 압축을 해제할 것이다. 테이프에 압축되어 백업한 파일의 목록을 확인하려고 한다면 tar tvf /dev/tape라고 하면 된다.

리눅스 시스템이 실행되는 과정(/etc/rc.d 관련 설명 포함)

1. power on

 

2. BIOS가 시스템 이상 여부 테스트

 

3. 부팅할 드라이브 선택 :부트로더

아주 예전에는 LILO(LInux LOader)를 사용했지만 21세기에 들어오며 grub를 사용한다. 부트로더는 주로 MBR(Master Boot Record)에 설치되어 여러 개의 커널로 부팅이 가능한 경우, 커널들이 어디에 위치하고 있는지에 관한 정보를 파악하고 있다가 사용자로 하여금 사용할 운영체제를 선택하게 하고 선택된 운영체제에 맞는 커널을 불러온다.

4. 선택된 드라이브의 MBR 읽어들임

 

5. MBR이 파티션 테이블을 읽어 부팅할 파티션을 알아냄

 

6. 커널 압축 해제

부트로더는 클럭을 초기화하고 커널을 메모리에 적재한다. 제어권이 커널에게 넘어가면 커널의 제일앞에 있는 코드가 실행되는데, 여기는 (사이즈를 줄이기 위해 압축된) 커널의 압축을 푸는 코드가 들어 있다.

 

7. 장착된 하드웨어 검사, 장치 드라이버 검사

 

8. 커널 / (root 파일 시스템)을 read-only로 마운트

 

9. 파일시스템 검사

 

10. /(root 파일시스템)을 read-write로 다시 마운트

 

11. /sbin/init 실행. hostname, swapping, 시스템점검, 커널모듈 로딩

 

12. /etc/rc.d/rc 실행: inittab에 정의된 Default Runlevel을 실행

– 실행될 runlevel의 디렉토리 존재 여부의 확인
– 실행시킬 프로세스 중 이미 실행중인 것을 종료함
– /etc/rc.d/rc[0-6].d내의 S로 시작하는 스크립트 시행

 

/etc/rc.d/rc[0-6].d와 같은 디렉토리들을 찾을 수 있는데, 여기서 0~6은 실행 레벨이다. 숫자에 따른 실행 레벨은 다음과 같다.
– 0 : 시스템 종료 halt
– 1 : 단일 사용자 모드. 시스템이 최소화된 상태로 부팅
– 2 : 다중 사용자 모드, 단 NFS 지원하지 않음
– 3 : 다중 사용자 모드이며 네트워킹 지원. 텍스트 인터페이스로 사용할 수 있다.
– 4 : 사용자 정의 레벨
– 5 : X Window로 부팅되도록 할때
– 6 : Reboot

실행 레벨은 시스템의 사용 용도나 형편에 따라, 수행되어야 할 서비스들을 묶어 놓은 그룹이라 해석할 수 있다. 관리자만이 시스템에 접근해야 할 필요가 있을 경우에는 실행 레벨 1로, X 윈도우로 로그인하려면 실행 레벨 5로 정해주면, 시스템의 실행 레벨에 따라 알아서 그룹으로 묶여있는 서비스를 실행하거나 종료한다.

각 실행 레벨(runlevel)에 해당하는 디렉토리에는 각 레벨에 해당하는 자동 실행 스크립트의 링크 파일이 들어 있다. init는 시스템을 시작할 때 상황에 맞게 이 스크립트를 실행한다. 사용자의 편의대로 기본 실행레벨을 변경하려면 /etc/inittab에서 다음 부분과 같이 수정한다. (3 대신 원하는 레벨의 숫자를 넣는다)

# vi /etc/inittab
……
id:3:initdefault:
….

 

/etc/rc.d/rc[0-6].d 안의 스크립트들은 /etc/inittab 파일 중 ‘id’부분에 정의된 실행레벨에서 실행될 스크립트들을 실행한다. 이렇게 실행할 스크립트는 /etc/rc.d/rc[0-6].d 디렉토리에 들어있는데, 이 파일들을 알고 보면, /etc/rc.d/init.d 디렉토리에 실제적인 실행 스크립트를 추가하고, 실행하려는 레벨의 디렉토리에 링크를 만든 것이다. 앞에서 설명한 경우, 실행 레벨이 “3”이고, /etc/rc.d/rc3.d 디렉토리에 실행될 스크립트를 가리키는 링크들이 들어있다.

 

그 링크 이름을 살펴보면, 파일 이름의 첫 번째 문자는 두 가지 중 하나라는 사실을 알 수 있다. 그 중 하나는 kill, 즉 중단을 의미하는 “K” 이며, 다른 하나는 start, 즉 시작을 나타내는 ”S” 이다. 예컨대 “K30Sendmail” 는 ‘/etc/rc.d/init.d/sendmail stop’ 으로, ”S10network”는 ‘/etc/rc.d/init.d/network start’로 실행된다. 이 지시문자 뒤에 있는 숫자는 실행 순서를 나타내는 것으로, 번호가 앞서는 것이 먼저 실행된다.

 

13. /etc/rc.d/rc.local : 부팅될 때 마다 이 디렉토리를 읽으므로, 매번 실행할 내용을 넣어둔다. 이 경우 먼저 해당 실행 레벨의 스크립트가 실행된 다음 이 내용을 실행한다.

 

14. /etc/rc.d/rc.serial : 시리얼 포트를 초기화한다.

 

15. login(getty) / X window(xdm)를 실행하면 익숙한 GUI화면을 볼 수 있다.

 

여기까지의 과정은 dmseg 명령이나 #cat /var/log/message 명령으로 다시 확인할 수 있다.

주민등록번호 체크방법(자바스크립트, plsql)

주민번호를 총 13자리 배열이라고 할 때

0~11까지의 인덱스에 각각 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5를 곱한다.

인덱스별로 곱한 결과를 모두 더하고, 그 값을 11로 나눈 후 나머지를 구한다.

나머지에서 11을 뺀 수가 13번째 숫자값이 된다. (나머지가 10 이상이면 1의 자리만 비교)

 

자바스크립트로 주민번호 체크

 

function checkIt(jumin){
var juminArray =  null;
juminArray = stringToIntArray(jumin);
alert( checkJM(juminArray) );
}

function checkJM(juminArray) {
var _CHECKDIGIT = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5];
var _BASEDIGIT = 11;
var sumVal = 0;

for(var i = 0; i < 12; i++) {
sumVal += (juminArray[i] * _CHECKDIGIT[i]);
}

temp = _BASEDIGIT – (sumVal % _BASEDIGIT);
temp = (temp == 10) ? 0 : temp;
temp = (temp == 11) ? 1 : temp;

return (temp == parseInt(juminArray[12])) ? true : false;
}

function stringToIntArray(str) {
var intArray = new Array(str.length);

for(var i = 0; i < intArray.length; i++) {
intArray[i] = parseInt(str.charAt(i));
}

return intArray;
}

오라클 plsql로 주민번호 체크

/* FUNCTION F_JUMIN_CHECK(JUMIN VARCHAR2)  */
/* return : Right = ‘Y’, False = ‘N’                       */

CREATE OR REPLACE FUNCTION F_JUMIN_CHECK(JUMIN VARCHAR2) RETURN CHAR
AS
TYPE TJ_ARRAY IS TABLE OF NUMBER(2) INDEX BY BINARY_INTEGER;
TYPE TCK_ARRAY IS TABLE OF NUMBER(2) INDEX BY BINARY_INTEGER;

R_VALUE CHAR(1);
T_SUM NUMBER(3) := 0;
V_TEMP NUMBER(3);

TJ TJ_ARRAY;
TCK TCK_ARRAY;

BEGIN

TCK(1) := 2;
TCK(2) := 3;
TCK(3) := 4;
TCK(4) := 5;
TCK(5) := 6;
TCK(6) := 7;
TCK(7) := 8;
TCK(8) := 9;
TCK(9) := 2;
TCK(10) := 3;
TCK(11) := 4;
TCK(12) := 5;

FOR X IN 1..13 LOOP
TJ(X) := TO_NUMBER(SUBSTR(JUMIN, X, 1));
END LOOP;

 

FOR X IN 1..12 LOOP
T_SUM := T_SUM + (TCK(X) * TJ(X));
END LOOP;

V_TEMP := 11 – MOD(T_SUM, 11);

IF V_TEMP = 10 THEN
V_TEMP := 0;
ELSIF V_TEMP = 11 THEN
V_TEMP := 1;
END IF;

IF V_TEMP = TO_NUMBER(TJ(13)) THEN
R_VALUE := ‘Y’;
ELSE
R_VALUE := ‘N’;
END IF;

RETURN R_VALUE;
END;
/