function makeObj() {
let num = 0
let obj = {}
for (let i = 65; i <= 122; i++) {
if (!(i > 90 && 97 > i))
obj[String.fromCharCode(i)] = [Math.round(num * 10000) / 10000, Math.round((Math.round((num += 0.018) * 10000) / 10000 - 0.0001) * 10000) / 10000]
}
obj[' '] = [0.936, 0.9539]
obj['end'] = [0.954, 1]
return obj
}
function compression(str) {
let obj = makeObj()
let compressionRange = [0, 1]
let num_2 = '0.'
for (let i = 0; i < str.length; i++) {
const sub = subFun(compressionRange[1], compressionRange[0])
compressionRange[1] = rangeFun(compressionRange[0], sub, obj[str[i]][1])
compressionRange[0] = rangeFun(compressionRange[0], sub, obj[str[i]][0])
}
const sub = subFun(compressionRange[1], compressionRange[0])
compressionRange[1] = rangeFun(compressionRange[0], sub, obj['end'][1])
compressionRange[0] = rangeFun(compressionRange[0], sub, obj['end'][0])
while (!(compressionRange[0] <= binaryStrToDecimalNum(num_2) && binaryStrToDecimalNum(num_2) <= compressionRange[1])) {
if (compressionRange[1] < binaryStrToDecimalNum(num_2 + '1')) num_2 += '0'
else num_2 += '1'
}
return num_2
}
function decompress(binaryStr) {
let obj = makeObj()
let decompressRange = [0, 1]
let finish = false
let result = ''
const decimalNum = binaryStrToDecimalNum(binaryStr)
while (!finish) {
for (let key in obj) {
let copyDecryptRange = decompressRange.slice()
const sub = copyDecryptRange[1] - copyDecryptRange[0]
copyDecryptRange[1] = rangeFun(copyDecryptRange[0], sub, obj[key][1])
copyDecryptRange[0] = rangeFun(copyDecryptRange[0], sub, obj[key][0])
if (copyDecryptRange[0] <= decimalNum && decimalNum <= copyDecryptRange[1]) {
decompressRange = copyDecryptRange
if (key === 'end') finish = true
else result += key
break
}
}
}
return result
}
function binaryStrToDecimalNum(binaryStr) {
let result = 0
let underNum = binaryStr !== '0.' ? binaryStr.slice(2) : '0'
for (let i = 0; i < underNum.length; i++) {
if (underNum[i] === '1') result += 0.5 ** (i + 1)
}
return result
}
function rangeFun(range0, sub, objKey) {
let decimalRange0Lenght = Number.isInteger(range0) ? 0 : String(range0).length - 2,
decimalSubLenght = Number.isInteger(sub) ? 0 : String(sub).length - 2,
decimalObjKeyLenght = Number.isInteger(objKey) ? 0 : String(objKey).length - 2
let longLenght = Math.max(decimalRange0Lenght, decimalSubLenght + decimalObjKeyLenght)
return Math.round((range0 + sub * objKey) * 10 ** longLenght) / 10 ** longLenght
}
function subFun(a, b) {
let decimalALenght = Number.isInteger(a) ? 0 : String(a).length - 2,
decimalBLenght = Number.isInteger(b) ? 0 : String(b).length - 2
let longLenght = Math.max(decimalALenght, decimalBLenght)
return Math.round((a - b) * 10 ** longLenght) / 10 ** longLenght
}
function compressionArr(str) {
let compressionedArr = []
for (let i = 0; i < str.length; i += 6) {
compressionedArr.push(compression(str.slice(i, i + 6)))
}
return compressionedArr
}
function decompressArr(arr) {
let decompressed = ''
arr.forEach(e => {
decompressed += decompress(e)
})
return decompressed
}
let compressioned = compressionArr('Hi my name is ChoiManSeon')
console.log(compressioned)
let decompressed = decompressArr(compressioned)
console.log(decompressed)
//!
// let compressioned = compression('manseon')
// console.log('compressioned', compressioned)
// let decompressed = decompress(compressioned)
// console.log('decompressed', decompressed)
문제점
현재 코드가 6글자씩 잘라서 압축을 하고 있는데 그 보다 더 많은 글자를 압축하면 깨진다
그 이유는 js의 경우 소수점 16번째까지만 표현이 되기때문에 더 이상 압축이 안된다
또한 현재 압축되서 나오는 값이
[
'0.001000110010001101100011001101010100011',
'0.10110101111010011101101000111000010011',
'0.1100111100001011100000110011001001101001',
'0.0011100101111111110100111001001011101111',
'0.1011100001'
]
이렇게 나오는데 문자열이라서 용량이 더 큰건지.. 이진수로 읽혀서 작은지 잘 모르겠다
그렇다고 Number을 씌우면
Number('0.001000110010001101100011001101010100011')
->
0.001000110010001101
뒤가 잘려버린다 js는 산술부호화압축에 쓰기 적합하지않아보인다
참고
https://ko.wikipedia.org/wiki/%EC%82%B0%EC%88%A0_%EB%B6%80%ED%98%B8%ED%99%94
산술 부호화 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 산술 부호화(算術符號化, 영어: Arithmetic coding)는 무손실 압축에 사용되는 엔트로피 부호화 알고리즘 가운데 하나이다. 다른 엔트로피 부호화 알고리즘이 각각
ko.wikipedia.org
'코딩 공부 > 공부' 카테고리의 다른 글
docker (0) | 2022.10.03 |
---|---|
nginx (0) | 2022.10.03 |
nodemailer를 이용한 mail보내기 (0) | 2022.06.08 |
환경변수 사용법 (react, webpack, aws) (0) | 2022.06.02 |
**연산자에대한 고찰 (1) | 2022.05.31 |