字节存储数据
一个字节有8个bit,一个int一般情况下有32个bit(4个字节),一个long有64个bit(8个字节)。
对于一个数据:
0123456789
我们可以用10个int来存储,共占用40个字节。如果用10个long来存储,则共占用80个字节,如果用10个char来存储,则共占用10个字节。
int有32个bit,其表示范围为2^(-31)~2^31-1
long有64个bit,其表示范围为2^(-63)~2^63-1
char有8个bit,其表示范围为2^(-7)~2^7-1,如果是unsigned char,其表示范围为0~2^8-1
显然int、long、char的表示能力过大,造成多余的bit浪费。
我们的数据是0~10,10个数,只要n个bit的情况大于等于10即可,显然这里n应该为4。
所以,对于上面的数据,我们用4个bit来表示一个数:
4个bit |
数据 |
0000 |
0 |
0001 |
1 |
0010 |
2 |
0011 |
3 |
0100 |
4 |
0101 |
5 |
0110 |
6 |
0111 |
7 |
1000 |
8 |
1001 |
9 |
我们可以用一个unsigned char来存储2个数据,比如:
10000110
表示的数据为:
86
10000110实际的值用十进制表示为134,用十六进制表示为0x86
所以,我们可以对该unsigned char进行十六进制的转换,即可得到实际存储的数据:
0x86 ---------------------> 86
假如,我们用十进制的86来存储实际的数据86,会怎么样呢?
十进制86的二进制位:
01010110
如果我们想根据01010110,得到实际数据86,需要对该unsigned char进行十进制的转换。
下面是具体的程序:
// 字节存储数据 #include <iostream> #include <string> #include <vector> using namespace std; // 十六进制字节存储 vector<unsigned char> ByteStoreHex(const string& data, vector<unsigned char>& byteMemory) { byteMemory.clear(); if (data.size() % 2 == 0) // byteMemory首个元素用来存储数据元素数的奇偶性 { byteMemory.push_back('0'); } else { byteMemory.push_back('1'); } int i = 0; for (i = 0; i < data.size() - 1; i += 2) { unsigned char ch = (data[i] - '0') * 16 + (data[i + 1] - '0'); byteMemory.push_back(ch); } if (i == data.size() - 1) { unsigned char ch = (data[data.size() - 1] - '0') * 16; byteMemory.push_back(ch); } return byteMemory; } void displayByteMomeryHex(const vector<unsigned char>& byteMemory) { for (auto i = 1; i < byteMemory.size() - 1; ++i) { cout << hex << "0x"; if (byteMemory[i] < 16) { cout << '0'; } cout << (int)byteMemory[i] << ' '; } if (byteMemory[0] == '0') { cout << hex << "0x"; if (byteMemory[byteMemory.size() - 1] < 16) { cout << '0'; } cout << (int)byteMemory[byteMemory.size() - 1]; } else { cout << hex << "0x" << (int)(byteMemory[byteMemory.size() - 1] / 16); } cout << endl; } string ByteReadHex(const vector<unsigned char>& byteMemory, string& data) { data.clear(); for (auto i = 1; i < byteMemory.size() - 1; ++i) { unsigned char tmpstr[3] = {0}; if (byteMemory[i] < 16) { tmpstr[0] = '0'; itoa(byteMemory[i], (char*)(tmpstr + 1), 16); } else { itoa(byteMemory[i], (char*)tmpstr, 16); } data += tmpstr[0]; data += tmpstr[1]; } unsigned char tmpstr[3] = {0}; if (byteMemory[byteMemory.size() - 1] < 16) { tmpstr[0] = '0'; itoa(byteMemory[byteMemory.size() - 1], (char*)(tmpstr + 1), 16); } else { itoa(byteMemory[byteMemory.size() - 1], (char*)tmpstr, 16); } if (byteMemory[0] == '0') { data += tmpstr[0]; data += tmpstr[1]; } else { data += tmpstr[0]; } return data; } // 十进制字节存储 vector<unsigned char> ByteStoreDec(const string& data, vector<unsigned char>& byteMemory) { byteMemory.clear(); if (data.size() % 2 == 0) // byteMemory首个元素用来存储数据元素数的奇偶性 { byteMemory.push_back('0'); } else { byteMemory.push_back('1'); } int i = 0; for (i = 0; i < data.size() - 1; i += 2) { unsigned char ch = (data[i] - '0') * 10 + (data[i + 1] - '0'); byteMemory.push_back(ch); } if (i == data.size() - 1) { unsigned char ch = (data[data.size() - 1] - '0') * 10; byteMemory.push_back(ch); } return byteMemory; } void displayByteMomeryDec(const vector<unsigned char>& byteMemory) { cout << dec; for (auto i = 1; i < byteMemory.size() - 1; ++i) { if (byteMemory[i] < 10) { cout << '0'; } cout << (int)byteMemory[i] << ' '; } if (byteMemory[0] == '0') { if (byteMemory[byteMemory.size() - 1] < 10) { cout << '0'; } cout << (int)byteMemory[byteMemory.size() - 1]; } else { cout << (int)(byteMemory[byteMemory.size() - 1] / 10); } cout << endl; } string ByteReadDec(const vector<unsigned char>& byteMemory, string& data) { data.clear(); for (auto i = 1; i < byteMemory.size() - 1; ++i) { unsigned char tmpstr[3] = {0}; if (byteMemory[i] < 10) { tmpstr[0] = '0'; itoa(byteMemory[i], (char*)(tmpstr + 1), 10); } else { itoa(byteMemory[i], (char*)tmpstr, 10); } data += tmpstr[0]; data += tmpstr[1]; } unsigned char tmpstr[3] = {0}; if (byteMemory[byteMemory.size() - 1] < 10) { tmpstr[0] = '0'; itoa(byteMemory[byteMemory.size() - 1], (char*)(tmpstr + 1), 10); } else { itoa(byteMemory[byteMemory.size() - 1], (char*)tmpstr, 10); } if (byteMemory[0] == '0') { data += tmpstr[0]; data += tmpstr[1]; } else { data += tmpstr[0]; } return data; } int main() { string data = "0123456789"; vector<unsigned char> byteMemory; ByteStoreHex(data, byteMemory); displayByteMomeryHex(byteMemory); cout << ByteReadHex(byteMemory, data) << endl; cout << endl; ByteStoreDec(data, byteMemory); displayByteMomeryDec(byteMemory); cout << ByteReadDec(byteMemory, data) << endl; cout << endl << endl; data = "9876543201"; ByteStoreHex(data, byteMemory); displayByteMomeryHex(byteMemory); cout << ByteReadHex(byteMemory, data) << endl; cout << endl; ByteStoreDec(data, byteMemory); displayByteMomeryDec(byteMemory); cout << ByteReadDec(byteMemory, data) << endl; cout << endl << endl; data = "0123456789876543210"; ByteStoreHex(data, byteMemory); displayByteMomeryHex(byteMemory); cout << ByteReadHex(byteMemory, data) << endl; cout << endl; ByteStoreDec(data, byteMemory); displayByteMomeryDec(byteMemory); cout << ByteReadDec(byteMemory, data) << endl; cout << endl; return 0; }
以上程序中,data为要存储和读取的数据,vector<unsigned char>为内部的字节存储,由于data中数据元素个数存在奇偶性的情况,我们将vector<unsigned char>的第一个元素用来表示data中数据元素个数的奇偶性。
如果数据范围不只是0~9十个数据,还包括其他的字符,比如a~z,如果这样的话,一个数据不能用4个bit来表示,可以用8个bit来表示,即一个unsigned char。
对于日期的数据比如20130912,可以采用4个bit存一个单位数据的。
如果是身份证号,则尽量不用4个bit,而是可以用8个bit直接表示,因为最后一位有可能是’X’,所以unsigned char足够存储。
用8个bit来存储数据,直接copy就行了,即从string中将每个元素copy到vector<unsigned char>中即可,这是存储的过程。读取的时候也是直接将vector<unsigned char>中每个元素依次拷贝到string中即可。
数据的存储基本可以理解为数据的编码和解码,存储相对于存储,读取相对于解码。数据存储和读取以及数据的加密和解密,还有数据的编码和解码都是有意思的事儿。