aaaaabbbc
라는 문자열을 a5b3c1
으로 압축하는 기술입니다.00 47 FF 6F 05 64 20 6A 6F 62 21
00
을 8 bit로 바꿔보면 0000 0000 인데, 밑줄 친 곳이 MSB(가장 왼쪽 자리)입니다.(00 + 1)
= 1
개 읽어옵니다. 00의 다음 1바이트는 47
입니다. 이걸 결과물에 추가합니다.47
FF
는 8 bit로 바꿔보면[1] 1111 1111 인데, MSB = 1입니다.(257 - FF)
= (257 - 255)
= 2
회 반복합니다. 이걸 결과물에 추가합니다.47 6F 6F
05
는 8 bit로 바꿔보면 0000 0101 인데, MSB = 0입니다.(05 + 1)
= 6
개 읽어옵니다. 05의 다음 6개 바이트는 64 20 6A 6F 62 21
입니다. 이걸 결과물에 추가합니다.47 6F 6F 64 20 6A 6F 62 21
47 6F 6F 64 20 6A 6F 62 21
는 아스키(ASCII) 코드로 바꾸면 Good job!
이 됩니다.00 47 FF 6F 05 64 20 6A 6F 62 21
라는 11 byte의 문자열로 압축(?)을 했음에도 용량이 오히려 늘어나는 것을 보여줍니다.<?php
// RLE 압축 풀기
function RLEdecode($encoded_source, $file_size)
{
for($l=0; $l<$file_size; $l++) {
$indata[$l] = ord(substr($encoded_source, $l, 1));
}
$l=0;
$j=0;
$k=0;
while($l < $file_size) {
$num = $indata[$l];
// MSB 체크. 128=1000 0000 이므로 127보다 크면 MSB=1, 아니면 MSB=0
if($num > 127) {
$num = 257 - $num; // 가져올 다음 문자 개수
for($k=1; $k<=$num; $k++) {
$decodedData[$j+$k-1] = $indata[$l+1];
}
$l++;
$j = $j+$k-1;
} else {
for($k=1; $k<=$num+1; $k++) {
$decodedData[$j+$k-1] = $indata[$l+$k];
}
$l = $l+$k-1;
$j = $j+$k-1;
}
$l++;
}
return $decodedData;
}
// TD4 파일의 경로 지정
$file_path = './coaster.TD4';
$file_size = filesize($file_path);
// 파일 내용 읽기
$fp = fopen($file_path, 'r');
$encoded_source = @fread($fp, $file_size);
fclose($fp);
// RLE 복호화
$data = RLEdecode($encoded_source, $file_size);
/*
흥미도 출력. 흥미도는 16진수로 33번째, 10진수로 51번째에 있다.
PHP 배열의 인덱스에는 10진수를 쓰므로 [] 사이에 51 입력.
TD4 파일 포맷 문서 참고.
*/
echo '흥미도는 '.($data[51]/10);
TELKwiki에 기여함은 TELKLAND의 이용 약관에 동의함을 뜻합니다.