-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathbasehangul.php
More file actions
110 lines (102 loc) · 3.03 KB
/
basehangul.php
File metadata and controls
110 lines (102 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<?php
/*
* ------------------------------------------------
* basehangul - Human-readable binary encoding
* ------------------------------------------------
* works with EUC-KR.
* Extended Wansung is not needed :D
*
* 2014/10/09 Harukana Sora (twitter.com/koreapyj)
* Last Change: 2014/11/05
*
*/
class BaseHangul {
private $padding, $charset;
function __construct($charset = 'UTF-8') {
$this->padding = chr(0xC8).chr(0xE5);
$this->charset = $charset;
}
function encode($data) {
$input = array(0,0,0,0,0);
$output= array(0,0,0,0);
$result = '';
$len = strlen($data);
for($i=0;$i<$len;$i++) {
$index=$i%5;
$input[$index] = ord(substr($data, $i, 1));
if($index==4 || $i==$len-1) {
$output[0] = (($input[0] & 0xFF) << 2) | (($input[1] & 0xC0) >> 6);
$output[1] = (($input[1] & 0x3F) << 4) | (($input[2] & 0xF0) >> 4);
$output[2] = (($input[2] & 0x0F) << 6) | (($input[3] & 0xFC) >> 2);
$output[3] = (($input[3] & 0x03) << 8) | (($input[4] & 0xFF) );
$result.=$this->dechangul($output[0]);
$result.=!$output[1] && $index <= 1?$this->padding:$this->dechangul($output[1]);
$result.=!$output[2] && $index <= 2?$this->padding:$this->dechangul($output[2]);
$result.=!$output[3] && $index < 3?$this->padding:$this->dechangul($index==3?$output[3]>>8|1024:$output[3]);
unset($input);
}
}
return iconv('EUC-KR', $this->charset, $result);
}
function decode($data) {
$data = iconv($this->charset, 'EUC-KR', $data);
$output = array(0, 0, 0, 0, 0);
$result = '';
for($i=0;$i<mb_strlen($data, 'EUC-KR');) {
$output[0]=$output[1]=$output[2]=$output[3]=$output[4]=-1;
for($j=$i;$j<$i+4;$j++) {
$input[$j%4]=$this->hanguldec(mb_substr($data, $j, 1, 'EUC-KR'));
}
$i=$j;
switch(0) {
case 0:
$output[0] = ($input[0] & 0x3FC) >> 2;
$output[1] = (($input[0] & 0x3) << 6) | (($input[1] & 0x3F0) >> 4);
if($input[1]===false) {
if($output[1] == 0)
$output[1] = -1;
break;
}
$output[2] = (($input[1] & 0xF) << 4) | (($input[2] & 0x3C0) >> 6);
if($input[2]===false) {
if($output[2] == 0)
$output[2] = -1;
break;
}
$output[3] = (($input[2] & 0x3F) << 2) | ((($input[3]>1023?$input[3] ^ 1024 << 8:$input[3]) & 0x300) >> 8);
if($input[3]===false) {
if($output[3] == 0)
$output[3] = -1;
break;
}
$output[4] = ($input[3] & 0xFF);
if($input[3]>1023)
$output[4] = -1;
}
for($j=0;$j<5;$j++) {
if($output[$j]==-1)
continue;
$result.=chr($output[$j]);
}
}
return $result;
}
private function dechangul($num) {
if($num>1027) {
throw new Exception('Out of range');
return false;
}
return chr($num/0x5E+0xB0).chr($num%0x5E+0xA1);
}
private function hanguldec($hangul) {
if($hangul == $this->padding)
return false;
$code = hexdec(bin2hex($hangul));
$num = ($code & 0xFF) - 0xA1 + (($code >> 8 & 0xFF)-0xB0)*0x5E;
if($num > 1027 || $num < 0) {
throw new Exception('Not a valid BaseHangul string');
return false;
}
return $num;
}
}