2021-11-16 17:13 작성
비손실 압축 방법
대량의 데이터 처리를 위한 알고리즘으로 문자열에서 같은 값이 연속해서 나타나는 것을 그 문자의 개수와 반복되는 값으로 표현하여 더 짧은 문자열로 줄여서 표현함.
- “aabbaccc”: “2a2ba3c”
- “ababcdcdababcdcd”: “2ababcdcd”
- “abcabcdede”: “2abcdede”
메모
생각 1. 그렇다면 데이터의 길이에 따라 압축 방법이 달라지는 알고리즘을 사용한다면 압축된 데이터를 복구시킬 때 기준도 따로 저장해놓아야 복구가 가능하지 않나?
아래와 같은 이유로 데이터 복구의 기준이 보안의 key가 될 수 있을 것이라고 생각한다.
생각 2. 만약 알파벳이 아닌 숫자로 동일한 압축 방법을 사용한다면?
숫자의 중복 개수 만큼 알파벳으로 단위를 세는 것도 가능하다고 생각한다.
예를 들면,
b0
는 숫자 0을 2개 가지고 있는 것으로 계산하는 방식이다.
이것을 이용해 알파벳 방식과 같이 사용하게 되면 예측이 힘든 id 값을 만들 수 있을 것이다.
3ab2cd000c66 = abababcdcd000666666
생각 3. 그렇다면 이 방법을 어디서에서 활용할 수 있을까? 수 십, 수 백만 개의 데이터를 처리한다고 했을 때, 데이터 당 1개의 문자열만 늘어나도 전체 데이터 개수만큼 처리할 분량이 늘어난다.
예를 들어, 최대 1만의 길이를 가진다고 봤을 때, 숫자 혹은 숫자 + 문자로 조합한다고 해도 결국에는
1 <= x <= 10000
의 문자열 길이를 그대로 서버에 저장하게 된다. 그러나 문자열로만 지정한다고 하면 위와 같이 나올 수 있는 범위는 같지만 중복 되는 문자열을 압축하므로 서버에 저장되는 값을 상당히 감소시킬 수 있을 것이다.
따라서 이 알고리즘은 간단한 id를 설정하는 것부터 시작해서 데이터를 예측 가능한 범위에서 관리할 수 있게 하는 알고리즘이라고 생각한다.
예시
function solution(s) {
// 2a2ba3c: 7 (1개 단위), 2ababcdcd: 9(8개 단위), 2abcdede: 8(3개 단위)
// 자르는 범위 최소: 1, 최대: 문자열 길이
// 최소 단위부터 최대 단위까지 잘라 가며 그 다음의 값과 비교하고 같은 것을 묶어 "숫자 + 알파벳" 형태로 변환
let answer = slice(s);
console.log(answer); // { optLength: 7, optKey: 1 }
return answer.optLength;
}
const slice = (s) => {
// 자르기 단위로 완성한 문자열 저장
let prev = s;
let post = "";
// 최적 자르기 단위
let key = 0;
// 자르기 단위 정하기
for (let i=1; i<=s.length; i++) {
// 자른 단위로 이전 값과 비교 하기 위한 변수
let compare = "";
let count = 1;
// 자르기 단위 별로 looping
for (let k=0; k < s.length; k+=i) {
// 이전 문자와 같으면 count를 올리고 그렇지 않으면 compare에 새 문자 할당
if (compare === s.slice(k, k+i)) {
count ++;
} else {
post += (count > 1 ? count : "" ) + compare;
count = 1;
compare = s.slice(k, k+i);
}
// 마지막 범위에서 출력
if ((k+i) >= s.length) {
post += (count > 1 ? count : "" ) + compare;
count = 1;
}
}
if (prev.length >= post.length) {
prev = post;
key = i;
post = "";
} else post = "";
}
return { optLength: prev.length, optKey: key };
}