phpsource/파일분석2002. 9. 9. 16:39
TAR 아카이브를 구성하는 멤버 파일 및 디렉토리에 관한 모든 정보(헤더 및 본문)가 다 기록된 후에는 마지막으로 파일 내용과 관계없이 null로 채워진 1블록 이상의 빈블록(empty block)들이 붙여지게 됩니다.
예를 들어 TAR 아카이브 파일의 마지막에 임의로 추가되는 빈블록을 덤프해 보면 아래와 같이 null 문자만으로 채워져 있음을 알 수 있습니다.
< TAR 아카이브 파일의 마지막에 임의로 추가되는 빈블록 구조 >

'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}7.클래스  (0) 2002.09.09
{TAR 파일}6.zlib를 이용한 압축  (0) 2002.09.09
{TAR 파일}4.본문 구조  (0) 2002.09.09
{TAR 파일}3.헤더 구조  (1) 2002.09.09
{TAR 파일}2.아카이브 구조  (0) 2002.09.09
Posted by 방글24
phpsource/파일분석2002. 9. 9. 16:30
파일 헤더가 완성되었으면 뒤이어 파일 내용이 들어가게 됩니다. 파일 내용은 512 바이트의 배수로 기록됩니다. 만약 파일크기가 1바이트부터 512 바이트사이라면 1블록(512바이트)을 사용하고 513바이트부터 1024바이트까지는 2블록(1024바이트)을 사용하는 식입니다.
결국 TAR 아카이브에서의 파일 내용 부분이 차지하는 크기는 아래와 같은 식으로 구할 수 있습니다.
[code php;gutter:false] function calc_blocksize($realsize) {
return ceil($realsize / 512) * 512;
} [/code]
본문에서도 헤더 구조에서와 마찬가지로 채워지지 않은 빈 공간에 모두 null로 채워야 합니다.
파일크기가 0바이트인 파일인 경우에는 디렉토리인 경우와 마찬가지로 파일 헤더만 존재하며 본문은 기록되지 않습니다.
예를 들어 s1.txt 파일에 대한 본문 구조를 덤프해 보면 아래와 같습니다.
< s1.txt 파일에 대한 본문 구조 >

'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}6.zlib를 이용한 압축  (0) 2002.09.09
{TAR 파일}5.후미에 붙여지는 블록  (0) 2002.09.09
{TAR 파일}3.헤더 구조  (1) 2002.09.09
{TAR 파일}2.아카이브 구조  (0) 2002.09.09
{TAR 파일}1.개요  (0) 2002.09.09
Posted by 방글24
phpsource/파일분석2002. 9. 9. 16:11
TAR 아카이브 포맷
TAR 아카이브의 포맷을 보면 이전의 유닉스 호환 포맷(UNIX-compatible formats)과 POSIX (IEEE P1003.1) 기준으로 새로이 정의된 USTAR 포맷(USTAR format)이 있습니다. 새로이 정의된 USTAR 포맷은 유닉스 호환 포맷보다 더 많은 정보를 저장할 수 있으며 더 긴 파일 패스명을 지원합니다. 그러나 어느 포맷이 되었든지 헤더는 512바이트 크기의 1블록으로 구성되어 있습니다.
우선 이전의 유닉스 호환 포맷에 의한 헤더 구조를 보면 아래와 같습니다.
< 유닉스 호환 포맷에 의한 헤더 구조 >
FIELD NAME OFFSET SIZE MEANING
name 0 100 name of file
mode 100 8 file mode
uid 108 8 owner user ID
gid 116 8 owner group ID
size 124 12 length of file in bytes
mtime 136 12 modify time of file
chksum 148 8 checksum for header
link 156 1 indicator for links
linkname 157 100 name of linked file
link 필드에는 링크 파일(linked file)이면 1, 심볼릭 링크(symbolic link) 이면 2, 기타일 때는 0이 기록됩니다. 디렉토리의 경우에는 링크명에 슬래시(/)가 붙게되지요.
새로운 USTAR 포맷에 의한 헤더 구조는 아래와 같습니다. magic 필드에는 null 문자로 종료되는 문자열 "ustra"이 기록되며 magic 필드 이전의 모든 필드는 typeflag 필드를 제외하고는 모두 이전의 유닉스 호환 포맷과 동일합니다. 유닉스 호환 포맷에서의 link 필드가 USTAR 포맷에서는 typeflag 필드로 변경되었습니다.
< USTAR 포맷에 의한 헤더 구조 >
FIELD NAME OFFSET SIZE MEANING
name 0 100 name of file
mode 100 8 file mode
uid 108 8 owner user ID
gid 116 8 owner group ID
size 124 12 length of file in bytes
mtime 136 12 modify time of file
chksum 148 8 checksum for header
typeflag 156 1 type of file
linkname 157 100 name of linked file
magic 257 6 USTAR indicator
varsion 263 2 USTAR version
uname 265 32 owner user name
gname 297 32 owner group name
devmajor 329 8 device major number
devminor 337 8 device minor number
prefix 345 155 prefix for file name
이와 같이 어느 포맷이 되었든지 파일명, 파일크기 등 파일 정보에 관한 내용이 저장되는 헤더는 1블록(512바이트)로 구성되어 있습니다.
TAR 아카이브를 다룰 때 name 필드부터 typeflag 필드까지만 정확히 다루게 된다면 윈도우를 포함한 어느 시스템에서나 정상적으로 동작하는 것 같습니다. 즉 여러분이 PHP를 이용하여 작성된 TAR 아카이브를 가지고 유닉스 또는 리눅스의 tar 유틸리티를 이용하여 풀 수 있으며, 또한 윈도우에서 알집이나 window commander에서 풀 수도 있습니다.
테이블에 나타난 바와 같이 각 필드마다 그 위치와 크기가 고정되어 있습니다.
magic, uname, gname 필드는 마지막 코드는 반드시 null(아스키문자 0)이 나타나는 null 종료 문자열(null-terminated character strings)입니다. name, linkname, prefix 필드는 마지막 코드가 반드시 null일 필요는 없으나 정해진 필드크기가 다 채워지지 않았다면 채워지지 않은 빈 공간을 반드시 null로 채워야 합니다. name 필드의 예를 들어보면 만약 파일명이 "s1.txt"라면 name 필드에 기록될 때는 "s1.txt" . str_repeat(chr(0), 100 - strlen("s1.txt"))에서 얻은 값으로 기록됩니다.
USTAR 포맷에서 uname, gname 필드는 각각 로그인 사용자명과 그룹 사용자명을 기록합니다.
mode, uid, gid, chksum, devmajor, devminor 필드의 마지막 코드는 반드시 null이 기록되어야 하나 size, mtime, version 필드는 반드시 null로 종료할 필요는 없으나 일반적으로 null이 기록되는 것 같습니다. 따라서 숫자를 나타내는 이들 필드는 모두 null로 종료한다고 생각하시면 될 것입니다. 이와 같이 숫자를 나타내는 필드들은 모두 null로 종료되므로 실제로 숫자가 기록되는 장소의 크기는 테이블에 정하여진 SIZE-1이 됩니다. 예를 들어 uid의 경우를 보면 필드 크기는 8바이트이지만 실제로 OFFSET 108부터 114까지의 7바이트에만 기록되며 마지막 OFFSET 115에는 null이 기록됩니다. 숫자 필드에서 한가지 주의할 것은 기록되는 숫자는 10진수가 아니라 8진수로 기록된다는 것이지요. 그리고 기록되는 숫자의 자리수가 필드 크기보다 작을 때는 앞쪽으로 남는 자리수만큼 "0"으로 채워지게 됩니다. 만약 uid 값이 8이라면 uid 필드에는 "0000010"이 기록됩니다.
어떤 필드가 되었든지 헤더에서 사용되지 않는 공간은 모두 null로 채우도록 되어있습니다. 이제는 각 필드별로 다른 특징을 살펴보지요.
"name" 필드는 파일명 또는 디렉토리명이 기록되는 곳으로 총 100자까지 기록될 수 있습니다. 파일명이 100자가 되지 않아 비워있는 곳은 모두 null 값으로 채워집니다. 여기에 기록되는 파일명에는 패스명이 포함됩니다.
USTAR 포맷의 경우를 보면 prefix 필드의 값이 null이 아니라면 100자가 넘는 파일명이 가능하도록 name 필드 앞에 붙게 됩니다. 그러나 이전의 유닉스 호환 포맷이나 윈도우 시스템에서 TAR 아카이브를 만들 수 있는 윈도우커맨더 등과의 호환성을 생각한다면 prefix 필드를 null로 남겨두는 것이 좋을 듯하며 100자가 넘는 파일명인 경우 뒷쪽을 짤라내어 100자까지만 name 필드에 저장하는 것이 좋을 듯합니다.
USTAR 포맷에서만 사용하고 있는 typeflag 필드는 이전의 유닉스 호환 포맷의 link 필드와 호환성을 유지한 채 확장시킨 것입니다. 아래는 typeflag 필드에 기록될 수 있는 값들이며 이 중에 0, 1, 2까지는 이전의 유닉스 호환 포맷과 호환성을 유지합니다.
< typeflag 필드의 값 >
TYPE FLAG FILE TYPE
0 or null Regular file
1 Link to another file already archived
2 Symbolic link
3 Character special device
4 Block special device
5 Directory
6 FIFO special file
7 Reserved
A-Z Available for custom usage
"typeflag"는 파일 형식을 나타내는 필드로 디렉토리일 때는 "5"가 기록되며 파일일 경우에는 "0"이 기록됩니다.
"mode" 필드는 파일 모드가 기록되는 곳으로 8진수로 기록됩니다. 예를 들면 0755, 0644와 같지요. "mode" 필드에서 사용할 수 있는 크기는 총 7자입니다. 이 경우 보통 "0000755"와 같이 남는 공간은 앞쪽에 "0"으로 채우게 됩니다. 그러나 이러한 기록 방법은 프로그램에 따라 약간씩 차이가 나기도 하네요. 윈도우 유틸리티인 windows commander에서 TAR 아카이브를 만들게 되면 "000755 " 또는 "000644 "와 같이 6자만 8진수로 만들어 주고 7번째 자리에는 " "로 채우게 됩니다. 윈도우에서야 원래 파일 모드라는 개념이 없으니까 관계가 없다고 생각할지 모르겠으나 윈도우에서 압축한 TAR 아카이브를 리눅스에서 풀 때는 생각한다면 이를 적절히 처리하는 것이 좋을 것 같습니다.
"uid"와 "gid"도 "mode"와 같이 8진수로 기록되며 총 7자리를 만들 게 됩니다. 빈 공간은 앞쪽에 "0"을 채우게 되지요.
"size"는 바이트 단위의 파일 크기를 나타내며 8진수로 기록됩니다.
"mtime"는 파일을 수정한 시간을 나타내며 이에 해당하는 php 함수는 filemtime()입니다.
"magic" 필드는 압축 알고리즘의 이름을 나타내며 보통 "ustar" 또는 "GNUtar" 등이 기록됩니다. 6자가 안되는 부분은 " "로 뒤쪽에 채워지게 됩니다.
"linkname", "uname", "gname", "devmajor", "devminor", "prefix", "noname" 필드는 모두 chr(0)으로 채워넣습니다.
위와 같이 "chksum" 필드를 제외한 필드를 모두 기록한 후에 마지막으로 "chksum" 필드를 기록합니다. "chksum" 필드는 묶여진 파일이 정상적인가를 확인하는데 이용하는 체크섬 필드입니다. 8진수로 기록되며 채워지지 않는 부분은 앞쪽으로 "0"으로 채우게 됩니다. 체크섬 값은 아래와 같은 방법으로 구하게 됩니다. 이 때 변수 $HEADER에는 "chksum" 필드를 제외한 필드가 위에서 기술한 방법대로 먼저 기록되어 있다고 가정합니다.
[code php;gutter:false] function get_checksum() {
global $HEADER;

$sum = 0;

for ($i=0;$i<512;$i++) {
if ($i < 148 || 156 < $i) {
$sum += ord($HEADER[$i]);
} else {
$sum += ord(" ");
}
}

return $sum;
} [/code]
만약 기록하고자 하는 것이 파일이 아니라 디렉토리라면 파일과 같은 내용이 없기 때문에 512바이트의 헤더만 존재합니다. 한번 디렉토리 정보가 기록되면 그 뒤의 파일들은 앞에서 나타난 디렉토리에 속하게 됩니다. 따라서 디렉토리가 변경되는 부분에서만 단 한번 디렉토리 정보가 기록됩니다. 앞에서도 설명하였지만 파일 헤더와 다른 점이라면 "typeflag" 필드값이 "5"라는 것과 "name" 필드에는 파일명 대신에 패스명이 기록됩니다. 예를 들면 "sub1/sub2/"와 같지요. 다른 필드는 파일일 때와 같습니다.
디렉토리 정보가 없이 파일을 묶었을 때의 헤더 구조
예를 들어 TAR 아카이브 파일 내용 중에서 s1.txt 파일에 대한 헤더 구조를 덤프(dump)해 보면 아래와 같습니다.
< s1.txt 파일에 대한 헤더 구조 >
디렉토리 정보와 함께 기록된 파일에 대한 헤더 구조
sub/s1.txt
sub/s2.txt
sub/s3.txt
만약 위에서와 같이 s1.txt, s2.txt, s3.txt 파일이 모두 동일한 디렉토리 sub에 존재하며 이를 묶을 때 디렉토리 정보 sub를 기록했을 때 TAR 아카이브의 s1.txt 파일에 대한 헤더 구조를 덤프해 보면 아래와 같습니다.
< 디렉토리 정보가 기록된 s1.txt 파일의 헤더 구조 >
디렉토리 정보를 기록한 헤더 구조
sub/s1.txt
sub/s2.txt
sub/s3.txt
만약 위에서와 같이 s1.txt, s2.txt, s3.txt 파일이 모두 동일한 디렉토리 sub에 존재하며 이를 묶을 때 디렉토리 정보 sub를 기록했을 때 TAR 아카이브의 sub 디렉토리 헤더 구조를 덤프해 보면 아래와 같습니다.
< sub 디렉토리에 대한 헤더 구조 >

'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}5.후미에 붙여지는 블록  (0) 2002.09.09
{TAR 파일}4.본문 구조  (0) 2002.09.09
{TAR 파일}2.아카이브 구조  (0) 2002.09.09
{TAR 파일}1.개요  (0) 2002.09.09
{HTML 파서}5.다운로드  (0) 2001.07.24
Posted by 방글24
phpsource/파일분석2002. 9. 9. 15:23
TAR 아카이브는 512바이트를 1블록으로하여 다루게 됩니다. 따라서 TAR 아카이브의 크기를 보면 512 * n 바이트임을 알 수 있습니다. TAR 아카이브는 여러 개의 파일이 하나로 묶여있으므로 각 멤버파일마다 본문 내용에 앞서 파일에 대한 정보를 기록하게 되는 1블록의 헤더가 반드시 나타나며 그 뒤를 이어 n블록의 본문 내용이 나타납니다. 때에 따라서는 하나의 디렉토리에 있는 파일뿐만 아니라 다른 디렉토리에 있는 파일들도 하나의 TAR 아카이브에 묶을 때도 있을 것입니다. 이러한 경우에는 디렉토리에 대한 정보도 기록하여야 하는데 이 경우에도 파일 헤더와 같이 1블록의 디렉토리 헤더를 가지게 됩니다. 디렉토리의 경우에는 파일과는 달리 본문 내용이 없으므로 각 디렉토리마다 1블록의 디렉토리 헤더만이 존재합니다. 파일 및 디렉토리에 관한 모든 정보(헤더 및 본문)가 다 기록된 후에는 마지막으로 아스키 0으로 채워진 1블록 이상의 빈블록(empty block)들이 붙여지게 됩니다.
이젠 몇가지 실예를 들어 전체 구조가 어떻게 구성되는지 살펴보겠습니다.
동일한 디렉토리에 있는 파일들(디렉토리 정보를 기록하지 않을 때)
아래와 같이 동일한 디렉토리에 있는 세 개의 파일(s1.txt, s2.txt, s3.txt)을 디렉토리 정보를 기록하지 않고 파일정보만 기록된 TAR 아카이브의 구조를 살펴보겠습니다.
s1.txt
s2.txt
s3.txt
s1.txt, s2.txt, s3.txt 파일이 모두 동일한 디렉토리에 존재하며 이를 묶을 때 디렉토리 정보를 전혀 기록하지 않는다면 TAR 아카이브의 전체 구조는 아래와 같을 것입니다.

s1.txt 파일 헤더

s1.txt 파일 본문

 

 

 

s2.txt 파일 헤더

s2.txt 파일 본문

 

 

 

s3.txt 파일 헤더

s3.txt 파일 본문

 

 

 

빈 블록

 

 

 

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

n 블록 (512 * n 바이트)

동일한 디렉토리에 있는 파일들(디렉토리 정보를 기록할 때)
아래와 같이 동일한 디렉토리에 있는 세 개의 파일(s1.txt, s2.txt, s3.txt)을 디렉토리 정보와 함께 기록된 TAR 아카이브의 구조를 살펴보겠습니다.
sub/s1.txt
sub/s2.txt
sub/s3.txt
s1.txt, s2.txt, s3.txt 파일이 모두 동일한 디렉토리 sub에 존재하며 이를 묶을 때 디렉토리 정보 sub를 기록한다면 TAR 아카이브의 전체 구조는 아래와 같을 것입니다.

sub 디렉토리 헤더

s1.txt 파일 헤더

s1.txt 파일 본문

 

 

 

s2.txt 파일 헤더

s2.txt 파일 본문

 

 

 

s3.txt 파일 헤더

s3.txt 파일 본문

 

 

 

빈 블록

 

 

 

1 블록 (512 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

n 블록 (512 * n 바이트)

여러 개의 디렉토리에 있는 파일들
s1.txt
s2.txt
sub1/s3.txt
sub1/sub2/s4.txt
sub1/sub2/s5.txt
sub1/sub2/sub3/s6.txt
sub4/s7.txt
s1.txt, s2.txt, s3.txt 파일이 여러 개의 디렉토리에 분산되어 존재하며 이를 묶을 때 이들 디렉토리 정보를 함께 기록한다면 TAR 아카이브의 전체 구조는 아래와 같을 것입니다.

s1.txt 파일 헤더

s1.txt 파일 본문

 

 

 

s2.txt 파일 헤더

s2.txt 파일 본문

 

 

 

sub1 디렉토리 헤더

s3.txt 파일 헤더

s3.txt 파일 본문

 

 

 

sub2 디렉토리 헤더

s4.txt 파일 헤더

s4.txt 파일 본문

 

 

 

s5.txt 파일 헤더

s5.txt 파일 본문

 

 

 

sub3 디렉토리 헤더

s6.txt 파일 헤더

s6.txt 파일 본문

 

 

 

sub4 디렉토리 헤더

s7.txt 파일 헤더

s7.txt 파일 본문

 

 

 

빈 블록

 

 

 

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

1 블록 (512 바이트)

1 블록 (512 바이트)

n 블록 (512 * n 바이트)

n 블록 (512 * n 바이트)


'phpsource > 파일분석' 카테고리의 다른 글

{TAR 파일}4.본문 구조  (0) 2002.09.09
{TAR 파일}3.헤더 구조  (1) 2002.09.09
{TAR 파일}1.개요  (0) 2002.09.09
{HTML 파서}5.다운로드  (0) 2001.07.24
{HTML 파서}4.배열 구조의 구성  (0) 2001.07.24
Posted by 방글24
phpsource/파일분석2002. 9. 9. 14:57
TAR(Tape ARchive) 아카이브 파일은 1970년대 자기테이프에 백업 & 검색하기 위하여 유래되었다고 합니다만 지금은 주로 여러 개의 파일을 묶어 전송하기 위하여 사용됩니다. 기본적으로 TAR 아카이브는 여러 개의 파일을 전혀 압축하지 않은 상태로 단지 하나의 파일로 묶어주는 역할만을 합니다. 우리가 보통 유닉스에서 제공하는 tar 유틸리티를 이용할 때 z 옵션을 지정하여 주면 압축까지 하는 것을 볼 수 있습니다. 그러나 이는 tar 유틸리티에서 압축해 주는 것이 아니라 tar 유틸리티와는 별개로 작성되어 있는 gzip 유틸리티를 불러다가 압축하게 되지요.
PHP 에서의 상황을 보면 zlib 라이브러리(gz로 시작하는 함수들)를 통해 파일을 압축할 수 있습니다. 그러나 zlib 함수는 기본적으로 하나의 파일만 다룰 수 있습니다. 웹상에서 여러 파일을 압축하고 해제하는 것이 다소 위험하여 그런지는 알 수 없으나 웹 스크립트에서는 TAR 아카이브를 잘 다루지 않는 것 같습니다. 생각해 보면 위험하기도 하겠습니다. 무슨 파일이 포함되었는지도 모르는 압축파일을 서버에 올려서 풀어버린다면 그 위험성은 상상하고도 남겠지요. 또한 내가 아닌 누군가가 나의 웹서버의 내용을 통째로 압축하여 가져가 버린다면...... 소름끼치는 상상이 될 수도 있겠지요. 그러나 구더기 무서워 장 못담그겠습니까? 서버상의 여러 개의 파일을 하나로 묶어서 다루어야 할 경우는 너무 많기때문에 TAR 아카이브를 다룰 수 있는 함수는 꼭 있어야 겠지요. 그리고 TAR 아카이브를 다룰 때 발생할 수 있는 여러 가지 위험성을 충분히 고려하여 사용하기만 한다면 별(?) 문제 없을 것입니다.
현재 PHP에서 일반적으로 웹상에서 여러 개의 파일을 압축하기 위해서는 exec() 또는 system()와 같은 함수와 리눅스에서 제공하는 tar 유틸리티를 이용하게 됩니다. 그러나 이러한 방법은 서버 상황에 따라 때로는 제대로 동작되지 않을 경우도 있으며 또한 윈도우 서버의 경우에는 해결방법이 될 수가 없습니다. 결국 가능한한 서버 환경에 관계없이 웹상에서 TAR 아카이브를 다루기 위해서는 TAR 아카이브를 직접 처리하는 것이 좋을 것 같습니다.
본인도 PHP에서 다중 파일 다운로드 클래스를 만들다보니 여러 개의 파일을 다운로드하기 위해서는 결국 여러 개의 파일을 하나의 파일로 묶은 후에 이 파일을 다운로드 받은 것이 가장 좋겠다는 생각까지는 하게 되었으나 현재 공개된 해결책으로는 위에서 언급한 리눅스의 tar 유틸리티를 이용하는 방법 외에는 눈에 띄는 것이 없었습니다. 그래서 인터넷을 검색하기 시작하였고 이를 통해 C로 작성된 tar 유틸리티의 소스 및 TAR 아카이브 구조에 관한 기술자료를 얻을 수 있었습니다. 이러한 자료를 통해 리눅스의 tar 유틸리티와 같은 기능을 수행하는 TAR 아카이브 클래스를 작성하게 되었습니다.
TAR 아카이브 관련 PHP 소스
TAR 관련 PHP 소스는 그리 흔한 것 같지 않습니다. 저도 관련 소스를 검색하여 보았으나 www.phpclasses.org에서 단 하나 발견하였을 뿐입니다. 본인도 이 소스를 참조하여 제 나름대로 TAR 아카이브를 다루는 클래스(hTarFile)를 작성하였습니다. 관심있는 분은 관련 소스들을 참조하시고 혹시 모르니 여러분도 인터넷을 더 검색해 보시기 바랍니다.
  • tar class
    Josh Barger
    joshb@npt.com
    http://www.phpclasses.org
  • hTarFile class
    Wookyung Hwang
    hwooky@phpclass.com
    http://www.phpclass.com
(추가) PEAR(PHP Extension and Application Repository)의 "File Formats" 패키지에 TAR 관련 PHP 소스 "Archive_Tar" 클래스가 있으니 http://pear.php.net 홈페이지를 참조바랍니다.
TAR 아카이브는 아니지만 zip 파일을 만들어 주는 소스가 보이네요. 소스는 TAR 아카이브를 다루는 것보다 훨씬 간단하구요. 실험해 보지는 않았지만 꽤 쓸모있는 소스인 것 같네요. 참조하세요.
  • zipfile class
    Eric Mueller
    eric@themepark.com
    http://www.zend.com/codex.php?id=696&single=1

Posted by 방글24
phpsource/회원인증2002. 2. 25. 14:30
파일 구성
adult.php - 성인 인증을 통과한 접속자에게 성인물을 제공함
로직
< 성인용 페이지 로직 >
성인 인증받지 못한 방문자 걸러내기
PHP 4.0.0 ~ 4.0.3일 때
[code php;gutter:false] session_start(); if (!isset($HTTP_SESSION_VARS["AdultCard"]) || "ok" != $HTTP_SESSION_VARS["AdultCard"]["permission"]) { // // 로그인을 거치지 않는 방문자 // ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; } $AdultCard = $HTTP_SESSION_VARS["AdultCard"]; // // 성인 인증 성공 // [/code]
성인 인증에 성공한 다음에 세션변수 $AdultCard를 다룰 때는 반드시 전역변수 $AdultCard를 가지고 다루시기 바랍니다. 그래야 변경된 세션변수값이 정상적으로 다음 페이지에 넘어갑니다.
PHP 4.0.4 ~ 4.0.5일 때
[code php;gutter:false] session_start(); if (!isset($HTTP_SESSION_VARS["AdultCard"]) || "ok" != $HTTP_SESSION_VARS["AdultCard"]["permission"]) { // // 로그인을 거치지 않는 방문자 // ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; } $AdultCard = & $HTTP_SESSION_VARS["AdultCard"]; // // 성인 인증 성공 // [/code]
성인 인증에 성공한 다음에 세션변수 $AdultCard를 다룰 때는 전역변수 $AdultCard 또는 $HTTP_SESSION_VARS["AdultCard"] 중 어느 것을 가지고 다루어도 관계없으나 가능하면 $HTTP_SESSION_VARS["AdultCard"]으로 다루도록 하세요. 그것이 향후 문서를 PHP 4.1.0으로 업그레이드할 때 작업하기가 편할 것입니다.
PHP 4.1.0 ~ 일 때
[code php;gutter:false] session_start(); if (!isset($_SESSION["AdultCard"]) || "ok" != $_SESSION["AdultCard"]["permission"]) { // // 로그인을 거치지 않는 방문자 // ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; } // // 성인 인증 성공 // [/code]
성인 인증에 성공한 다음에 세션변수 $AdultCard를 다룰 때는 전역변수 $AdultCard 대신에 $_SESSION["AdultCard"]을 가지고 다루어 주시기 바랍니다. 이렇게 하는 것이 보안성 측면에서 유리하다고 PHP 메뉴얼에 적혀있네요. 물론 $_SESSION 대신에 이전 버전부터 사용하던 $HTTP_SESSION_VARS를 이용하셔도 관계없습니다만 향후 업그레이드될 때의 호환성을 고려한다면 $_SESSION이 더 나을 것 같습니다.
성인용 게시물
위에서와 같이 성인 인증을 거친 방문자에게는 적절한(?) 내용을 보여주어야 겠지요. 그 내용은 저도 모릅니다. 알아서 하세요. 단 로그아웃을 위한 메뉴 하나 정도는 꼭 필요하겠지요.
[code html;gutter:false] <HTML> <HEAD> <TITLE>성인용 페이지</TITLE> </HEAD> <BODY> // // 성인용 게시물(내용 생략) // <A href="./logout.php">로그아웃</A> </BODY> </HTML> [/code]

Posted by 방글24
phpsource/회원인증2002. 2. 25. 14:26
파일 구성
logout.php - 로그아웃 처리
로직
< 로그아웃처리 페이지 로직 >
소스 코드
각 버전별로 작성된 코드를 보면 session_unset 함수를 이용하여 모든 세션변수를 해제시키지 않고 세션변수 $AdultCard 에 대하여만 해제시키도록 하였습니다. 세션 함수를 본 성인 인증 소스만 사용한다면 session_unset 함수로 모든 세션변수를 해제시켜도 관계없지만 만약 성인 인증 소스 외에 현 웹사이트의 다른 문서에서도 세션 함수를 사용해야 한다면 성인 인증 소스에서만 사용하고 있는 세션변수 $AdultCard 만 해제시켜야 다른 문제가 발생하지 않습니다.
PHP 4.0.0 ~ 4.0.5일 때
[code php;gutter:false] <?php session_start(); session_unregister("AdultCard"); ?> <META http-equiv='refresh' content='0; url=home.php'> [/code]
PHP 4.1.0 ~ 일 때
[code php;gutter:false] <?php session_start(); unset($_SESSION["AdultCard"]); ?> <META http-equiv='refresh' content='0; url=home.php'> [/code]

Posted by 방글24
phpsource/회원인증2002. 2. 25. 13:29
파일 구성
login.php - 홈페이지에서 입력된 주민등록번호를 가지고 성인 인증을 수행함
로직
< 홈페이지 로직 >
처음 접속자 확인, 주민등록번호 2차 검증 및 성인 판정에 따른 분기
PHP 4.0.0 ~ 4.0.3일 때
[code php;gutter:false] session_start(); if (!isset($HTTP_SESSION_VARS["AdultCard"])) { // // 웹사이트에 처음 접속했거나 로그아웃한 경우 // ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; } $AdultCard = $HTTP_SESSION_VARS["AdultCard"]; if ($birth=check_jumin($HTTP_POST_VARS["j1"], $HTTP_POST_VARS["j2"])) { // // 주민등록번호가 정상적으로 입력된 경우 // if (19 <= check_age(substr($birth, 0, -1))) { // // 성인(만19세 이상)인 경우 // $AdultCard["permission"] = "ok"; ?> <META http-equiv='refresh' content='0; url=adult.php'> <?php exit; } } // // 주민등록번호가 틀렸거나 성인이 아닌 경우 // $AdultCard["permission"] = "no"; ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; [/code]
PHP 4.0.4 ~ 4.0.5일 때
[code php;gutter:false] session_start(); if (!isset($HTTP_SESSION_VARS["AdultCard"])) { // // 웹사이트에 처음 접속했거나 로그아웃한 경우 // ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; } $AdultCard = & $HTTP_SESSION_VARS["AdultCard"]; if ($birth=check_jumin($HTTP_POST_VARS["j1"], $HTTP_POST_VARS["j2"])) { // // 주민등록번호가 정상적으로 입력된 경우 // if (19 <= check_age(substr($birth, 0, -1))) { // // 성인(만19세 이상)인 경우 // $HTTP_SESSION_VARS["AdultCard"]["permission"] = "ok"; ?> <META http-equiv='refresh' content='0; url=adult.php'> <?php exit; } } // // 주민등록번호가 틀렸거나 성인이 아닌 경우 // $HTTP_SESSION_VARS["AdultCard"]["permission"] = "no"; ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; [/code]
PHP 4.1.0 ~ 일 때
[code php;gutter:false] session_start(); if (!isset($_SESSION["AdultCard"])) { // // 웹사이트에 처음 접속했거나 로그아웃한 경우 // ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; } if ($birth=check_jumin($_POST["j1"], $_POST["j2"])) { // // 주민등록번호가 정상적으로 입력된 경우 // if (19 <= check_age(substr($birth, 0, -1))) { // // 성인(만19세 이상)인 경우 // $_SESSION["AdultCard"]["permission"] = "ok"; ?> <META http-equiv='refresh' content='0; url=adult.php'> <?php exit; } } // // 주민등록번호가 틀렸거나 성인이 아닌 경우 // $_SESSION["AdultCard"]["permission"] = "no"; ?> <META http-equiv='refresh' content='0; url=home.php'> <?php exit; [/code]
주민등록번호 2차 검증
주민등록번호 체계
현재 주민등록번호는 1975년부터 사용된 것으로 모두 13개 숫자로 돼 있습니다. 최초 6개 숫자는 생년월일을 나타내고, 뒤쪽 7개 숫자는 출생연대, 성별, 주민등록번호 발급기관, 신고순위 등으로 이루어진 다소 복잡한 구조로된 조합으로 그 조합체계는 공개되어 있지 않습니다.
조합체계에 대한 정확한 내용은 알 수 없으나 아래에 있는 주민등록법 개정행동연대에서 올린 "주민등록번호 체계"에 대한 글을 보시면 그 체계의 일부나마 알 수 있을 것입니다. 확인된 바는 없지만 이러한 조합체계는 시대에 따라(?) 약간의 유동이 있었던 것 같습니다. 따라서 현재 공개되는 주민등록번호 유효성 검증 소스들에는 거의 모두 약간의 오류를 포함하고 있지 않나 생각합니다.
주민등록번호 체계 -- 주민등록법개정행동연대
(수정:2010.1.11) 오래된 문서라서 현재는 링크가 깨진 상태입니다. 주민등록번호 체계에 대하여는 아래를 참조하세요.
우리나라의 주민등록제도는 1962년 주민등록법의 제정으로 처음 도입되었으며, 1975년 주민등록법시행령과 시행규칙의 개정으로 생년월일, 성별, 지역을 식별할 수 있도록 된 13자리의 숫자체제로 바뀌어 현재까지 사용되고 있습니다.
앞의 여섯자리 숫자는 생년월일을 나타냅니다. 뒤의 7자리 숫자는 출생연대, 성별, 주민등록번호 발급기관, 신고순위 및 오류검증번호를 나타냅니다.
뒤의 7자리 숫자 중 맨 앞자리 숫자는 출생연대와 성별을 나타냅니다. 예를 들면, 1900년대에 태어난 남자는 1번, 여자는 2번, 2000년대에 태어난 남자는 3번, 여자는 4번이 부여됩니다.
두 번째 자리부터 다섯번째 자리까지의 네자리 숫자는 최초 주민등록번호 발급기관의 고유번호, 여섯번째 자리는 신고순위, 마지막 일곱번째 숫자는 주민등록번호가 맞는지 여부를 증명해주는 오류수정 번호입니다.
주민번호체계 : YYMMDD - ABCDEFG

YYMMDD : 생년월일
예) 790309

A는 성별을 표시합니다.
예) 2000년대 남자 - 3, 여자 - 4
1900년대 남자 - 1, 여자 - 2
1800년대 남자 - 9, 여자 - 0

BCDE : 최초 주민등록번호 발급기관의 고유번호

F : 주민등록지에서 그 생년월일로 신고된 순서

G : 앞의 숫자들을 조합, 계산하여 산출되는 오류검증번호
주민등록번호 검증 함수
[code php;gutter:false] check_jumin($jumin1, $jumin2) [/code]
지정된 주민등록번호가 유효하면 생년월일 및 성별을 나타내는 문자열을, 틀리면 false를 반환한다. $jumin1은 주민등록번호 중 앞쪽 6자리의 숫자를 나타내는 문자열이며, $jumin2는 뒷쪽 7자리의 숫자를 나타내는 문자열입니다.
반환되는 값의 예를 보면 1991년 1월 12일에 출생한 남성이라면 "19910112M"을 반환하고 여성이라면 "19910112F"를 반환합니다. 아래는 이 함수에 대한 전체 소스입니다. 참고로 말씀드린다면 이와같은 검증 소스를 응용하여 주민등록번호를 임의로 생성해 주는 소스를 제작, 배포하는 것은 현행법상 엄연한 범법행위로 처벌받게 된다는 것을 명심하시기 바랍니다.
[code php;gutter:false] function check_jumin($jumin1, $jumin2) { if(strlen($jumin1) != 6 || strlen($jumin2) != 7) { return false; } $jumin = $jumin1 . $jumin2; for ($i=$sum=0;$i<12;$i++) { $sum += intval($jumin[$i]) * (($i % 8) + 2); } // // Checksum // if ((11 - ($sum % 11)) % 10 != intval($jumin[12])) { return false; } // // 총13자리의 주민등록번호 중 7번째의 숫자는 1부터 4까지의 값을 갖는다. // 이 값에 따라 성별 및 Y2K가 확인된다. // $a = intval($jumin[6]); if ($a < 1 || 4 < $a) { return false; } $sex = ($a % 2) ? "M" : "F"; $year = ($a < 3) ? 1900 : 2000; // // 출생년 확인 // $year += intval(substr($jumin1, 0, 2)); // // 출생월 확인 // $month = intval(substr($jumin1, 2, 2)); if($month < 1 || 12 < $month) { return false; } // // 출생일 확인(각 달에 따른 날수 차이 및 윤달 고려) // $day = intval(substr($jumin1, 4, 2)); $days = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); // // 2월생이면 윤달 확인 // if (2 == $month && check_leapyear($year)) { $days[1] = 29; } if(($day < 1) || ($days[$month-1] < $day)) { return false; } // // 반환값 // // 남성이면 "yyyymmddM", 여성이면 "yyyymmddF" // return "$year" . substr($jumin1, 2) . $sex; } [/code]
여기에 기술된 소스는 제가 작성한 것이 아니고 아래의 출처에서 밝힌 바와 같이 김순제 님이 작성하신 것에 약간의 수정만 가한 것입니다. 이 소스가 정확히 주민등록번호를 검증할 수 있는 것인지에 대하여는 확신할 수가 없네요. 제가 정확한 주민등록번호 검증 알고리즘을 본 일이 없기 때문에 이미 공개된 것을 그대로 가져왔습니다.
제작 : 김순제 님(soonj@lct.co.kr)
수정 : 후키(hwooky@phpclass.com)
따라서 여기서 공개된 성인 인증 소스는 공부삼아 보시기 바라며 진짜로 성인 사이트를 제작하시려거든 아래 업체에서 제공하는 실명확인 서비스를 받아 성인 인증을 수행하기 바랍니다. 실명확인 서비스란 실명과 주민등록번호가 일치하는지 확인해 주는 서비스를 의미하며 이를 이용하기 위해서는 아래 업체에서 해당 서비스를 신청하여야 합니다.
한국신용평가정보㈜(www.kisinfo.co.kr)
정보통신진흥협회(www.kait.or.kr)
한국신용정보(www.idcheck.co.kr)
윤년 확인 함수
주민등록번호의 유효성을 검증하는 과정에서 윤년 여부를 확인하게 됩니다. 아래와 같은 윤년 확인 로직에 의해 출생년도가 윤년인지 확인한 후 윤년인 경우에는 2월달을 29일까지 계산하면 윤년이 아닌 경우에는 28일까지 계산하여 주민등록번호 유효성을 검증합니다.
< 윤년 확인 로직 >
이러한 기능을 수행하는 것이 check_leapyear 함수이며 이 함수를 실행한 결과 윤년이면 true를, 윤년이 아니면 false를 반환합니다.
[code php;gutter:false] check_leapyear($year) [/code]
성인 확인
정보통신망이용촉진및정보보호 등에 관한 법률 및 청소년보호법 모두를 만족하는 성인 나이가 만 19세 이상인지 연 19세 이상인지는 제가 법률적 지식이 없어 잘 모르겠으나 현재 대부분의 성인 사이트들이 만19세 이상을 성인으로 인증하고 있으며 이에 따라 제가 공개하는 성인 사이트용 인증 소스도 만 19세 이상을 기준으로 인증하고 있습니다. 만약 향후 만 19세 이상이 아니고 연 19세 이상으로 그 기준이 변경되었을 경우에는 성인 확인 부분을 약간 수정하셔야 할 것입니다. 그러나 연나이는 우리나라 나이보다 1살 적기 때문에 "현재년도 - 주민등록년도"라는 수식으로 쉽게 구할 수 있습니다.
참고삼아 말씀드린다면 2001년 5월 24일 개정된 청소년보호법 제2조제1호에 의하면 청소년의 기준이 만나이에서 연나이로 변경되었는데 그 내용을 보면 아래와 같이 정의되어 있습니다.
"청소년"이라 함은 만 19세 미만의 자를 말한다.
다만, 만 19세에 도달하는 해의 1월 1일을 맞이한 자를 제외한다.
<<시행일 2001.8.25>>
`年나이'는 생일로부터 다음해 1월 1일을 지난 횟수만큼을 나이로 인정해 주는 방법으로 예를 들어 2001년 8월23일을 기준으로 1999년 9월 9일생의 경우 `滿나이'로는 한 살, 통상 국내에서 통용하는 나이개념으로는 세 살이 되지만 年나이로는 1월1일을 두 차례 지났기 때문에 두살이 됩니다.
`年나이 19세미만'으로 바뀌면 정상 나이의 대학 1년생의 경우 대학에 입학하는 해 1월1일부터 12월31일까지의 연 나이가 만19세로 돼 청소년보호법의 적용을 받지 않게 됩니다. 이는 생년월일에 따라 만 18세에서 만 19세로 전환되는 시점이 개인마다 달라 생일을 일일이 따져야 하는 불편과 대학 1년생에 대해서는 성인으로 간주하는 사회적 통념과의 괴리를 없애기 위한 것입니다.
滿나이 계산 함수
우리의 전통적인 나이 계산법에 의하면 아래와 같이 나이를 구할 수 있을 것입니다.
우리나라 나이 = 현재년도 - 주민등록년도 + 1
반면 서양식 나이 계산법인 만나이는 현재 생일이 지났을 경우에는 우리나라 나이보다 1살이 적고, 생일이 지나지 않았을 경우에는 2살이 적은 나이입니다. 이러한 만나이를 구하는 함수가 check_age입니다. 이 함수의 입력값으로는 "yyyymmdd" 형태의 문자열을 지정하여 줍니다. 예를 들면 1999년 5월 20일 생이면 "19990520"이 되는 것입니다. 이 함수를 실행하면 정수값으로 만나이를 반환시켜 줍니다.
[code php;gutter:false] check_age($birth) [/code]
이 함수의 전체 소스를 살펴보면 다음과 같습니다. 중간에 있는 $cur_year - $birth_year 의 결과가 바로 연나이에 해당합니다.
[code php;gutter:false] function check_age($birth) { $cur_year = intval(date("Y")); $birth_year = intval(substr($birth, 0, 4)); // // $age + 1 이 우리나라 나이임 // $age = $cur_year - $birth_year; // // month = 01 ~ 12 // day = 01 ~ 31 // $cur_day = intval(date("md")); $birth_day = intval(substr($birth, 4)); if ($cur_day <= $birth_day) { // // 생일이 지나지 않았으면 // $age--; } return $age; } [/code]

Posted by 방글24
phpsource/회원인증2002. 2. 25. 13:26
파일 구성
home.php - 1. 주민등록번호 입력양식을 제공
                 2. 입력된 주민등록번호의 유효성 검증
                 3. 검증 결과에 따른 분기
로직
< 홈페이지 로직 >
세션을 이용한 접속자 상태 확인 및 그에 따른 처리
PHP 4.0.0 ~ 4.0.3일 때
[code php;gutter:false] session_start(); if (!isset($HTTP_SESSION_VARS["AdultCard"])) { // // 웹사이트에 처음 접속했거나 로그아웃한 경우 // session_register("AdultCard"); $HTTP_SESSION_VARS["AdultCard"] = array("permission"=>"no"); } $AdultCard = $HTTP_SESSION_VARS["AdultCard"]; if ("ok" != $AdultCard["permission"]) { // // 처음 접속하거나 로그인에 실패한 경우 주민등록번호 입력양식을 출력 // login_form(); } else { // // 로그인에 성공한 경우는 성인용 페이지로 직행 // ?> <META http-equiv='refresh' content='0; url=adult.php'> <?php } [/code]
PHP 4.0.4 ~ 4.0.5일 때
[code php;gutter:false] session_start(); if (!isset($HTTP_SESSION_VARS["AdultCard"])) { // // 웹사이트에 처음 접속했거나 로그아웃한 경우 // session_register("AdultCard"); $HTTP_SESSION_VARS["AdultCard"] = array("permission"=>"no"); } $AdultCard = & $HTTP_SESSION_VARS["AdultCard"]; if ("ok" != $HTTP_SESSION_VARS["AdultCard"]["permission"]) { // // 처음 접속하거나 로그인에 실패한 경우 주민등록번호 입력양식을 출력 // login_form(); } else { // // 로그인에 성공한 경우는 성인용 페이지로 직행 // ?> <META http-equiv='refresh' content='0; url=adult.php'> <?php } [/code]
PHP 4.1.0 ~ 일 때
[code php;gutter:false] session_start(); if (!isset($_SESSION["AdultCard"])) { // // 웹사이트에 처음 접속했거나 로그아웃한 경우 // $_SESSION["AdultCard"] = array("permission"=>"no"); } if ("ok" != $_SESSION["AdultCard"]["permission"]) { // // 처음 접속하거나 로그인에 실패한 경우 주민등록번호 입력양식을 출력 // login_form(); } else { // // 로그인에 성공한 경우는 성인용 페이지로 직행 // ?> <META http-equiv='refresh' content='0; url=adult.php'> <?php } [/code]
세션 변수 $AdultCard는 연관배열로 "permission" 배열요소의 상태에 따라 성인 인증을 받았는지 안받았는지를 구분합니다. 이 값이 "no"이면 처음 접속하였거나 로그인에 실패한 접속자가 되며, "ok"이면 이미 성인 인증을 받은 접속자임을 나타냅니다.
따라서 "no"일 때는 접속자의 주민등록번호를 입력받는 화면을 나타냄으로 접속자로 하여금 성인 인증이 필요하다는 것을 알려주게되며, "ok"일 때는 즉시 성인용 페이지로 직행하게 됩니다.
PHP 버전에 따라 코딩 방법을 약간씩 다르게 해 보았습니다. 오십보 백보이기는 하지만 그래도 버전별로 보안상 가장 나은 방법을 택하여 작성해 보았습니다. 제가 보안 전문가가 아니라 잘못 이해하고 작성된 것이 있을 지 모르겠네요. 그렇다면 Q & A 게시판을 이용하여 지적하여 주시기 바랍니다. 하위버전용으로 작성된 것은 상위버전에서도 사용될 수 있으나 그 반대로는 불가능합니다.
주민등록번호 입력 화면
< 주민등록번호 입력 >
처음 접속하였거나 앞에서 행한 로그인에서 인증에 실패한 경우에는 이와 같은 입력화면을 출력하여 성인 인증을 위한 주민등록번호를 입력받도록 합니다.
청소년유해매체물의 경우에는 청소년보호법 및 정보통신망이용촉진및정보보호 등에 관한 법률에 의하여 그 표시방법 및 청소년 접근을 제한할 수 있는 방법 등에 관하여 규정하고 있습니다. 성인 인증 소스를 공개하는 본인은 법률의 문외한으로 이 소스가 위의 청소년유해매체물에 대한 표기 및 접근차단 방법이 동법에 적합한지는 알지 못합니다. 따라서 여기서 공개하는 모든 인증 소스는 누구나 자유롭게 이용(복사,수정,배포,재배포)할 수 있으나, 사용중 발생할 수 있는 모든 문제(법규 위반에 따른 책임 소재 및 그 외 발생가능한 모든 피해)에 대하여 어떠한 책임도 질 수 없음을 알려드립니다.
[code html;gutter:false] <CENTER> <TABLE width="400" border="0" cellpadding="0" cellspacing="6"> <TR> <TD align="center" height="134" width=90%> <P> 이 정보내용은 청소년유해매체물로서 정보통신망이용촉진및정보보호 등에 관한 법률 및 청소년보호법의<BR>규정에 의하여 <IMG src="img/19-.gif" align="middle" width="100" height="28" border="0" alt="만19세 미만">의 청소년이 이용할 수 없습니다. </P> <P> 주민등록번호로 성인여부를 판단합니다. </P> </TD> </TR> <TR> <TD align="center" height="102"> <!-- 로그인 폼양식 출력 시작 --> <FORM name=form1 action="login.php" method=post> <TABLE width="350" border="0" cellpadding="0" cellspacing="6" bgcolor="#dbf09f"> <TR> <TD align="right"> 주민등록번호 </TD> <TD> <INPUT size=6 maxlength=6 name=j1 type=text onKeyUp="checkKey(this.form)"> -<INPUT size=7 maxlength=7 name=j2 type=password onKeyDown="checkKey(this.form)"> </TD> </TR> <TR> <TD align="center" height="30" colspan="2"> <INPUT type=button value="성인공간 입장" onClick="checkKey(this.form)"> </TD> </TR> </TABLE> </FORM> <!-- 로그인 폼양식 출력 종료 --> </TD> </TR> </TABLE> </CENTER> [/code]
주민등록번호 1차 검증
주민등록번호를 입력하게 되면 자바스크립트로 작성된 checkKey 함수에 의해 입력된 주민등록번호가 올바른 것인지 1차 검증하게 됩니다. 이 소스 역시 인터넷 상에 이미 공개된 소스로 정확한 검증은 아니며 개략적으로만 그 유효성을 검증할 수 있습니다. 자바스크립트로 더 정확하게 검증해주는 소스를 원한다면 PHPSCHOOL.COM에서 검색해 보세요. 찾을 수 있을 것입니다.
[code html;gutter:false] <SCRIPT language=javascript> <!-- function checkJumin(jumin1, jumin2) { var i, sum = 0; var str = jumin1 + jumin2; if (parseInt(jumin2) < 1000000 && parseInt(jumin2) > 4999999) return false; for (i=0,sum=0; i<12; i++) sum += (((i%8) + 2) * (str.charAt(i) - "0")); if (((11 - (sum % 11)) % 10) == str.charAt(12)) return true; return false; } function checkKey(form) { if (form.j1.value.length==6) form.j2.focus(); key = event.keyCode; if (key==13 || key==0) { if (form.j1.value.length != 6 || form.j2.value.length != 7) { alert("주민등록번호를 입력하세요."); form.j1.focus(); return; } if (checkJumin(form.j1.value,form.j2.value)==false) { alert("주민등록번호가 맞지 않습니다."); form.j1.focus(); return; } form.submit(); } } //--> </SCRIPT> [/code]
현재 페이지에서 입력된 주민등록번호를 1차 검증하여 통과된 경우에만 로그인 처리 페이지로 넘어가 2차 검증을 받게 됩니다. 일단 이곳에서 간략하게나마 입력된 주민등록번호의 유효성을 검증하여 잘못된 것은 다시 주민등록번호를 입력하도록 함으로써 서버의 부하를 다소나마 줄여줄 수 있을 것입니다.

Posted by 방글24
phpsource/회원인증2002. 2. 25. 11:34
세션함수를 이용한 성인용 사이트 인증소스입니다. 주민등록번호를 입력받아 성인용 페이지에 접근할 수 있도록 작성된 "성인 인증 소스"입니다. 작성되었습니다.
파일 구성
home.php  - 성인인증을 위한 주민등록번호 입력(홈페이지)
login.php   - 주민등록번호를 가지고 성인 인증을 수행함
logout.php - 로그아웃 처리
adult.php   - 성인 인증을 통과한 접속자에게 성인물을 제공함
성인 인증 로직
< 성인 인증 로직 >
주민등록번호가 유효한가를 검증하는 부분이 home.php에도 있고, login.php에도 있습니다. home.php에서는 자바스크립트를 이용하여 개략적으로 주민등록번호를 검증하여 줌으로써 주민등록번호를 엉터리로 입력할 경우에는 다음페이지로 넘어가지 않더라도 현재페이지에서 다시 주민등록번호를 입력하도록 유도하여 서버의 부담을 줄여줄 수 있습니다.
login.php에서는 PHP 코드를 사용하여 주민등록번호를 좀 더 정밀하게 검증하여 주게 됩니다.

Posted by 방글24