Skip to content

Instantly share code, notes, and snippets.

@rkt2spc
Last active March 21, 2016 08:35
Show Gist options
  • Save rkt2spc/965a2be1fcbca3ec9e99 to your computer and use it in GitHub Desktop.
Save rkt2spc/965a2be1fcbca3ec9e99 to your computer and use it in GitHub Desktop.
Encoder và Decoder cho vòng thi Nối Mạng Toàn Cầu cuộc thi Thách Thức 2016
#pragma once
#include <string>
#include <vector>
#include <math.h>
using namespace std;
class Decoder
{
public:
char K = 0;
string Decode(string encodedStr)
{
//Mỗi kí tự trong encodedStr đảm bảo giá trị < 6 bit
//Convert về giá trị 5 bit bằng cách bỏ bít thứ 6 bên trái <=> -32
for (int i = 0; i < encodedStr.size(); ++i)
encodedStr[i] -= 32;
// Đổi chuỗi thành mảng bit (mỗi kí tự chỉ 5 bit)
vector<bool> bits(encodedStr.size() * 5);
for (int i = 0; i < encodedStr.size(); ++i)
{
// Shift từng bit rồi AND với 1 để lấy bit cuối
for (int j = 0; j < 5; j++)
bits[i * 5 + (5 - j - 1)] = encodedStr[i] >> j & 1;
// 11001 >> j:0 == 11001; 11001 & 1 = 1;
// set tại (8 - j:0 - 1) : set bit 1 tại 7: ####1
// 11001 >> j:1 == 11100; 11100 & 1 = 0;
// set tại (8 - j:1 - 1) : set bit 0 tại 6: ###01
// ...
}
// Cắt dãy bit thành những đoạn 8 bit (cluster)
int decodedLen = bits.size() / 8; //Số lượng cluster
string decodedStr(decodedLen, '.'); // khởi tạo chuỗi với độ dài decodedLen "......"
for (int i = 0; i < decodedLen; ++i)
{
//Lấy 8 bit tại cluster thứ i và biểu diễn thành char
char c = BuildCharFromBits(bits, i * 8, 8);
//XOr với K để lấy char ban đầu
decodedStr[i] = c ^ K;
}
return decodedStr;
}
char BuildCharFromBits(vector<bool> bits, int start, int length)
{
char result = 0;
int end = start + length;
for (int i = start; i < end; ++i)
{
if (bits[i])
result += pow(2, end - i - 1);
}
return result;
}
};
#pragma once
#include <string>
#include <vector>
#include <math.h>
using namespace std;
class Encoder
{
public:
char K = 0;
string Encode(string origin)
{
// Xor mỗi ký tự với khóa K
for (int i = 0; i < origin.size(); ++i)
origin[i] ^= K;
// Đổi chuỗi thành mảng bit
vector<bool> bits(origin.size() * 8);
for (int i = 0; i < origin.size(); ++i)
{
// Shift từng bit rồi AND với 1 để lấy bit cuối
for (int j = 0; j < 8; j++)
bits[i * 8 + (8 - j - 1)] = origin[i] >> j & 1;
// 10111001 >> j:0 == 10111001; 10111001 & 1 = 1;
// set tại (8 - j:0 - 1) : set bit 1 tại 7: #### ###1
// 10111001 >> j:1 == 01011100; 01011100 & 1 = 0;
// set tại (8 - j:1 - 1) : set bit 0 tại 6: #### ##01
// ...
}
// Cắt dãy bit thành những đoạn 5 bit (cluster)
int encodedLen = bits.size() / 5; //Số lượng cluster
// Mối cluster 5 bit sẽ được chứa trong 1 char,
// nên dãy các cluster này sẽ được biểu diễn là 1 string
string encodedStr(encodedLen, '.'); // khởi tạo chuỗi với độ dài encodedLen "......"
for (int i = 0; i < encodedLen; ++i)
{
//Lấy 5 bit tại cluster thứ i và biểu diễn thành char
char c = BuildCharFromBits(bits, i * 5, 5);
// Thêm bit 1 vào bên trái cluster đó vì cluster có 5 bit
// nên điều này tương đương thêm bit 1 vào vị trí thứ 6
// tương đương + 2^5 tương đương + 32
encodedStr[i] = c + 32;
}
return encodedStr;
}
char BuildCharFromBits(vector<bool> bits, int start, int length)
{
char result = 0;
int end = start + length;
for (int i = start; i < end; ++i)
{
if (bits[i])
result += pow(2, end - i - 1);
}
return result;
}
};
#include "Encoder.h"
#include "Decoder.h"
#include <iostream>
void main()
{
Encoder encoder;
encoder.K = 32;
Decoder decoder;
decoder.K = encoder.K;
//// Test char builder: build 'a': 0110 0001 : 97
//cout << encoder.BuildCharFromBits(
// vector<bool> { 0, 1, 1, 0, 0, 0, 0, 1 },
// 0, 8
//) << endl;
// Để hoạt động chính xác thì độ dài chuỗi phải chia hết cho 5
string str = "HelloWorld";
string encodedStr = encoder.Encode(str);
cout << "Encoded: " + encodedStr << endl;
string decodedStr = decoder.Decode(encodedStr);
cout << "Decoded: " + decodedStr << endl; //Expect str
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment