#include "dsrcryption.h"
#include <QString>
#include <QTime>

DsrCryption::DsrCryption()
{
    m_initflag = 0;
    m_cryword = 0;
    memset(m_factors, 0, BYTES_OF_CRY_FACTORS);
}

// 初始化加密控制, 生成加密字和加密因子
int DsrCryption::InitDsrCryptionCtrl(int version, unsigned int cryword, const unsigned char * factors)
{
    int rslt = 0;

    m_initflag = 0;
    m_cryword = 0;
    memset(m_factors, 0, BYTES_OF_CRY_FACTORS);

    if (version >= 0)
    {
        rslt = CreateCryWord(version);
    }
    else
    {
        m_cryword = cryword;
    }

    if (rslt == 0)
    {
        rslt = CreateCryFactors(factors);
    }

    if (rslt == 0)
    {
        m_initflag++;
    }

    return rslt;
}

// 获取加密字
unsigned int DsrCryption::GetDsrCryptionWord()
{
    return m_cryword;
}

// 加密数据
int DsrCryption::EnCryption(unsigned char * pData, int size)
{
    if (pData == NULL || size <= 0)
    {
        return -1;
    }

    unsigned char thisfactors[BYTES_OF_CRY_FACTORS];
    unsigned char tempbuff[BYTES_OF_CRY_FACTORS];

    memcpy(thisfactors, m_factors, BYTES_OF_CRY_FACTORS);   // 拷贝临时的加密因子，做计算用

    int i, j;
    for (i = 0; i < size; i += BYTES_OF_CRY_FACTORS)
    {
        // 拷贝数据到临时buff
        int mv = 0;
        for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
        {
            if (i+j < size)
            {
                tempbuff[j] = pData[i+j];      // 拷贝数据
            }
            else
            {
                tempbuff[j] = 0;
            }

            mv += thisfactors[j];   // 累加因子，作为移动因子
        }

        // 移动数据
        if (i + BYTES_OF_CRY_FACTORS < size)
        {
            // 生成移动索引
            unsigned char mvidx[BYTES_OF_CRY_FACTORS];
            int idx, setdidx = BYTES_OF_CRY_FACTORS-1;
            for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
            {
                idx = (mv >> j) & 0x1f;
                for (int k = 0; k < j; k++)
                {
                    if (mvidx[k] == idx)
                    {
                        idx = setdidx;
                        do
                        {
                            int kk;
                            for (kk = 0; kk < j; kk++)
                            {
                                if (mvidx[kk] == idx)
                                {
                                    break;
                                }
                            }
                            if (kk < j)
                            {
                                idx--;
                            }
                            else
                            {
                                setdidx = idx-1;
                                break;
                            }
                        } while(1);
                        break;
                    }
                }
                mvidx[j] = idx;
            }

            // 移动数据
            unsigned char tempdat[BYTES_OF_CRY_FACTORS];
            memcpy(tempdat, tempbuff, BYTES_OF_CRY_FACTORS);

            for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
            {
                tempbuff[j] = tempdat[mvidx[j]];
            }
        }

        // 数据加密
        for (j = 0; i+j < size && j < BYTES_OF_CRY_FACTORS; j++)
        {
            tempbuff[j] ^= thisfactors[j];   // 异或加密
            pData[i+j] = tempbuff[j];        // 保存
        }

        // 下次的变幻因子
        int temp = 0;
        for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
        {
            temp += thisfactors[j];
            temp *= 3;
            temp += 1;
            temp /= 2;
            thisfactors[j] = temp;
        }
    }

    return 0;
}

// 解密数据
int DsrCryption::DeCryption(unsigned char * pData, int size)
{
    if (pData == NULL || size <= 0)
    {
        return -1;
    }

    if (pData == NULL || size <= 0)
    {
        return -1;
    }

    unsigned char thisfactors[BYTES_OF_CRY_FACTORS];
    unsigned char tempbuff[BYTES_OF_CRY_FACTORS];

    memcpy(thisfactors, m_factors, BYTES_OF_CRY_FACTORS);

    int i, j;
    for (i = 0; i < size; i += BYTES_OF_CRY_FACTORS)
    {
        // 拷贝数据到临时buff
        int mv = 0;
        for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
        {
            if (i+j < size)
            {
                tempbuff[j] = pData[i+j];      // 拷贝数据
            }
            else
            {
                tempbuff[j] = 0;
            }

            mv += thisfactors[j];   // 累加因子，作为移动因子
        }

        // 数据解密
        for (j = 0; i+j < size && j < BYTES_OF_CRY_FACTORS; j++)
        {
            tempbuff[j] ^= thisfactors[j];
        }

        // 数据移动回去
        if (i + BYTES_OF_CRY_FACTORS < size)
        {
            // 生成移动索引
            unsigned char mvidx[BYTES_OF_CRY_FACTORS];
            int idx, setdidx = BYTES_OF_CRY_FACTORS-1;
            for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
            {
                idx = (mv >> j) & 0x1f;
                for (int k = 0; k < j; k++)
                {
                    if (mvidx[k] == idx)
                    {
                        idx = setdidx;
                        do
                        {
                            int kk;
                            for (kk = 0; kk < j; kk++)
                            {
                                if (mvidx[kk] == idx)
                                {
                                    break;
                                }
                            }
                            if (kk < j)
                            {
                                idx--;
                            }
                            else
                            {
                                setdidx = idx-1;
                                break;
                            }
                        } while(1);
                        break;
                    }
                }
                mvidx[j] = idx;
            }

            // 移动数据
            unsigned char tempdat[BYTES_OF_CRY_FACTORS];
            memcpy(tempdat, tempbuff, BYTES_OF_CRY_FACTORS);

            for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
            {
                tempbuff[mvidx[j]] = tempdat[j];
            }
        }

        // 保存解密数据
        for (j = 0; i+j < size && j < BYTES_OF_CRY_FACTORS; j++)
        {
            pData[i+j] = tempbuff[j];        // 保存
        }

        // 下次的变幻因子
        int temp = 0;
        for (j = 0; j < BYTES_OF_CRY_FACTORS; j++)
        {
            temp += thisfactors[j];
            temp *= 3;
            temp += 1;
            temp /= 2;
            thisfactors[j] = temp;
        }
    }

    return 0;
}

// 生成加密字
int DsrCryption::CreateCryWord(int version)
{
    if (version < 0 || version > 250)
    {
        return -1;
    }

    int rdw;
    if (version == 0)
    {
        rdw = 0;
    }
    else
    {
        QTime time= QTime::currentTime();
        qsrand(time.msec()+time.second()*1000);
        rdw = qrand();             // 产生随机数
    }

    m_cryword = rdw & 0xffffff;
    m_cryword *= 251;
    m_cryword += version;

    return 0;
}

// 生成加密因子
int DsrCryption::CreateCryFactors(const unsigned char * factors)
{
    if (factors == NULL)
    {
        return -1;
    }
    memcpy(m_factors, factors, BYTES_OF_CRY_FACTORS);

    int * pDat = (int*)m_factors;

    // 变幻加密因子，兼容非加密情况
    for (int i = 0; i < BYTES_OF_CRY_FACTORS; i+=sizeof(int))
    {
        *pDat *= m_cryword;
        pDat++;
    }
    return 0;
}







