본문 바로가기
Language/C++

[ C++ ] 8bits string을 unsigned char로 file에 압축하여 저장하기

by 신인용 2020. 11. 15.
반응형

 

8bits string을 unsigned char로 file에 압축하여 저장하기

 

 

 

목표

string 형태인 8bits binary 를 file에 1byte 크기로 넣기

즉, string을 unsigned char로 변환하는 작업을 수행할 것이다.

 

 

 

문제점

이진수를 binary 파일을 열어 입력해보았다.

결과는 string 형태인 8bits 이진수를 file에 쓰면 8개의 char가 쓰이게 된다.

이는 8byte 크기로 저장되는 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <fstream>
 
using namespace std;
 
void encoder(const string& txt) {
    ofstream fout;
    fout.open("encodingText.txt", ios::out | ios::binary);
 
    fout << txt;
}
 
int main()
{
    string txt = "00101001";
    encoder(txt);
 
}
cs

 

 

8개의 char가 저장되어 8바이트의 크기의 파일이 돼버렸다...

 

 

 

 

 

해결방안

string으로 file에 쓰지 말고, unsigned char로 file에 쓰자.

unsigned char의 표현범위는 0~255 이니, 정확하게 8개의 bits를 표현할 수 있다. (2^8 = 256)

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
#include <iostream>
#include <fstream>
 
using namespace std;
 
void encoder(unsigned char compressedTxt) {
    ofstream fout;
    fout.open("encodingText.txt", ios::out | ios::binary);
    fout << compressedTxt;
}
 
unsigned char compress(string& txt) {
    unsigned char sum = 0;
    for (int i = 0; i < 8; i++) {
        sum = (sum << 1| (txt[i] & 1); // string -> unsigned char
    }
    return sum;
}
 
int main()
{
    string txt = "00101001";
    unsigned char compressedTxt = 0// 0~255
 
    compressedTxt = compress(txt);
    encoder(compressedTxt);
}
cs

 

하나의 unsigned char를 저장해 1바이트 크기의 파일을 만들 수 있었다.

 

 

 

 

그리고

string txt = "001010000010100100100001001110011010100100101001"

총 48bits로 파일출력을 해보았다.

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
#include <iostream>
#include <fstream>
#include <vector>
 
using namespace std;
 
void encoder(const vector<unsigned char>& compressedTxt) {
    ofstream fout;
    fout.open("encodingText.txt", ios::out | ios::binary);
 
    for (unsigned char i : compressedTxt) {
        fout << i;
    }
}
 
vector<unsigned char> compress(string& txt) {
    vector<unsigned char> sums;
    unsigned char sum = 0;
    int lim = txt.size() / 8;
 
    for (int i = 0; i < lim; i++) {
        sum = 0;
        for (int j = 0; j < 8; j++) {
            sum = (sum << 1| (txt[i*8+j] & 1);
        }
        sums.push_back(sum);
    }
    
    return sums;
}
 
int main()
{
    string txt = "001010000010100100100001001110011010100100101001";
    vector<unsigned char> compressedTxt; // 0~255
 
    compressedTxt = compress(txt);
    encoder(compressedTxt);
}
cs

 

48bits string을 48/8 = 6 byte로 파일에 출력할 수 있었다.

 

 

 

 

결론

bits를 string으로 저장하는 것보단, unsigned char로 8bits씩 끊어서 저장하는게 효율적이라는 결론을 얻었다.

그리고 이를 효율적으로 이용한 것이 바로 "허프만 압축"이다. 이에 대한 글은 다른 글에 포스팅되어 있다.

-> 허프만 압축 구현

 

반응형

'Language > C++' 카테고리의 다른 글

[ C++ ] OOP - (1)  (0) 2020.08.05
[ C++ ] Reference (참조)  (0) 2020.03.03
[ C++ ] Manipulator (조정자)  (1) 2020.02.18

댓글