zoukankan      html  css  js  c++  java
  • 字节存储数据

    字节存储数据

             一个字节有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中即可。

             数据的存储基本可以理解为数据的编码和解码,存储相对于存储,读取相对于解码。数据存储和读取以及数据的加密和解密,还有数据的编码和解码都是有意思的事儿。

  • 相关阅读:
    Flutter——限制按钮点击的时间间隔
    【友盟】添加埋点事件(以iOS和安卓端为例)
    Git——在VSCode中查看Git历史提交记录
    Flutter——【好用网站】大集合
    Flutter——数组(List)
    Flutter——实现强大的输入框功能
    基于腾讯位置服务定位实现物业巡检防作弊场景
    基于腾讯地图定位组件实现周边公用厕所远近排序分布图
    腾讯位置服务Flutter业务实践——地图SDK Flutter插件实现(一)
    微信小程序类快递自动填写收发货地址功能
  • 原文地址:https://www.cnblogs.com/unixfy/p/3317998.html
Copyright © 2011-2022 走看看