kmdcodec.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,508 行 · 第 1/3 页

CPP
1,508
字号
    for (unsigned int idx = 0; idx < count; idx++)    {        // Adhere to RFC 2045 and ignore characters        // that are not part of the encoding table.        unsigned char ch = data[idx];        if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||            (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')        {            out[outIdx++] = Base64DecMap[ch];        }        else        {            len--;            tail--;        }    }    // kdDebug() << "Tail size = " << tail << ", Length size = " << len << endl;    // 4-byte to 3-byte conversion    len = (tail>(len/4)) ? tail-(len/4) : 0;    unsigned int sidx = 0, didx = 0;    if ( len > 1 )    {      while (didx < len-2)      {          out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));          out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));          out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077));          sidx += 4;          didx += 3;      }    }    if (didx < len)        out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));    if (++didx < len )        out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));    // Resize the output buffer    if ( len == 0 || len < out.size() )      out.resize(len);}QCString KCodecs::uuencode( const QCString& str ){    if ( str.isEmpty() )        return "";    QByteArray in;    in.resize( str.length() );    memcpy( in.data(), str.data(), str.length() );    return uuencode( in );}QCString KCodecs::uuencode( const QByteArray& in ){    QByteArray out;    uuencode( in, out );    return QCString( out.data(), out.size()+1 );}void KCodecs::uuencode( const QByteArray& in, QByteArray& out ){    out.resize( 0 );    if( in.isEmpty() )        return;    unsigned int sidx = 0;    unsigned int didx = 0;    unsigned int line_len = 45;    const char nl[] = "\n";    const char* data = in.data();    const unsigned int nl_len = strlen(nl);    const unsigned int len = in.size();    out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );    // split into lines, adding line-length and line terminator    while (sidx+line_len < len)    {        // line length        out[didx++] = UUEncMap[line_len];        // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion        for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)        {            out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];            out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |                                   (data[sidx] << 4) & 077];            out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |                                (data[sidx+1] << 2) & 077];            out[didx++] = UUEncMap[data[sidx+2] & 077];        }        // line terminator        //for (unsigned int idx=0; idx < nl_len; idx++)        //out[didx++] = nl[idx];        memcpy(out.data()+didx, nl, nl_len);        didx += nl_len;    }    // line length    out[didx++] = UUEncMap[len-sidx];    // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion    while (sidx+2 < len)    {        out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];        out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |                               (data[sidx] << 4) & 077];        out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |                               (data[sidx+1] << 2) & 077];        out[didx++] = UUEncMap[data[sidx+2] & 077];        sidx += 3;    }    if (sidx < len-1)    {        out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];        out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |                               (data[sidx] << 4) & 077];        out[didx++] = UUEncMap[(data[sidx+1] << 2) & 077];        out[didx++] = UUEncMap[0];    }    else if (sidx < len)    {        out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];        out[didx++] = UUEncMap[(data[sidx] << 4) & 077];        out[didx++] = UUEncMap[0];        out[didx++] = UUEncMap[0];    }    // line terminator    memcpy(out.data()+didx, nl, nl_len);    didx += nl_len;    // sanity check    if ( didx != out.size() )        out.resize( 0 );}QCString KCodecs::uudecode( const QCString& str ){    if ( str.isEmpty() )        return "";    QByteArray in;    in.resize( str.length() );    memcpy( in.data(), str.data(), str.length() );    return uudecode( in );}QCString KCodecs::uudecode( const QByteArray& in ){    QByteArray out;    uudecode( in, out );    return QCString( out.data(), out.size()+1 );}void KCodecs::uudecode( const QByteArray& in, QByteArray& out ){    out.resize( 0 );    if( in.isEmpty() )        return;    unsigned int sidx = 0;    unsigned int didx = 0;    unsigned int len = in.size();    unsigned int line_len, end;    const char* data = in.data();    // Deal with *nix "BEGIN"/"END" separators!!    unsigned int count = 0;    while ( count < len && (data[count] == '\n' || data[count] == '\r' ||            data[count] == '\t' || data[count] == ' ') )        count ++;    bool hasLF = false;    if ( strncasecmp( data+count, "begin", 5) == 0 )    {        count += 5;        while ( count < len && data[count] != '\n' && data[count] != '\r' )            count ++;        while ( count < len && (data[count] == '\n' || data[count] == '\r') )            count ++;        data += count;        len -= count;        hasLF = true;    }    out.resize( len/4*3 );    while ( sidx < len )    {        // get line length (in number of encoded octets)        line_len = UUDecMap[ (unsigned char) data[sidx++]];        // ascii printable to 0-63 and 4-byte to 3-byte conversion        end = didx+line_len;        char A, B, C, D;        if (end > 2) {          while (didx < end-2)          {             A = UUDecMap[(unsigned char) data[sidx]];             B = UUDecMap[(unsigned char) data[sidx+1]];             C = UUDecMap[(unsigned char) data[sidx+2]];             D = UUDecMap[(unsigned char) data[sidx+3]];             out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );             out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );             out[didx++] = ( ((C << 6) & 255) | (D & 077) );             sidx += 4;          }        }        if (didx < end)        {            A = UUDecMap[(unsigned char) data[sidx]];            B = UUDecMap[(unsigned char) data[sidx+1]];            out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );        }        if (didx < end)        {            B = UUDecMap[(unsigned char) data[sidx+1]];            C = UUDecMap[(unsigned char) data[sidx+2]];            out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );        }        // skip padding        while (sidx < len  && data[sidx] != '\n' && data[sidx] != '\r')            sidx++;        // skip end of line        while (sidx < len  && (data[sidx] == '\n' || data[sidx] == '\r'))            sidx++;        // skip the "END" separator when present.        if ( hasLF && strncasecmp( data+sidx, "end", 3) == 0 )            break;    }    if ( didx < out.size()  )        out.resize( didx );}/******************************** KMD5 ********************************/KMD5::KMD5(){    init();}KMD5::KMD5(const char *in, int len){    init();    update(in, len);}KMD5::KMD5(const QByteArray& in){    init();    update( in );}KMD5::KMD5(const QCString& in){    init();    update( in );}void KMD5::update(const QByteArray& in){    update(in.data(), int(in.size()));}void KMD5::update(const QCString& in){    update(in.data(), int(in.length()));}void KMD5::update(const unsigned char* in, int len){    if (len < 0)        len = qstrlen(reinterpret_cast<const char*>(in));    if (!len)        return;    if (m_finalized) {        kdWarning() << "KMD5::update called after state was finalized!" << endl;        return;    }    Q_UINT32 in_index;    Q_UINT32 buffer_index;    Q_UINT32 buffer_space;    Q_UINT32 in_length = static_cast<Q_UINT32>( len );    buffer_index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3F);    if (  (m_count[0] += (in_length << 3))<(in_length << 3) )        m_count[1]++;    m_count[1] += (in_length >> 29);    buffer_space = 64 - buffer_index;    if (in_length >= buffer_space)    {        memcpy (m_buffer + buffer_index, in, buffer_space);        transform (m_buffer);        for (in_index = buffer_space; in_index + 63 < in_length;             in_index += 64)            transform (reinterpret_cast<const unsigned char*>(in+in_index));        buffer_index = 0;    }    else        in_index=0;    memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);}bool KMD5::update(QIODevice& file){    char buffer[1024];    int len;    while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)        update(buffer, len);    return file.atEnd();}void KMD5::finalize (){    if (m_finalized) return;    Q_UINT8 bits[8];    Q_UINT32 index, padLen;    static const unsigned char PADDING[64]=    {        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0    };    encode (bits, m_count, 8);    //memcpy( bits, m_count, 8 );    // Pad out to 56 mod 64.    index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3f);    padLen = (index < 56) ? (56 - index) : (120 - index);    update (reinterpret_cast<const char*>(PADDING), padLen);    // Append length (before padding)    update (reinterpret_cast<const char*>(bits), 8);    // Store state in digest    encode (m_digest, m_state, 16);    //memcpy( m_digest, m_state, 16 );    // Fill sensitive information with zero's    memset ( (void *)m_buffer, 0, sizeof(*m_buffer));    m_finalized = true;}bool KMD5::verify( const KMD5::Digest& digest){    finalize();    return (0 == memcmp(rawDigest(), digest, sizeof(KMD5::Digest)));}bool KMD5::verify( const QCString& hexdigest){    finalize();    return (0 == strcmp(hexDigest().data(), hexdigest));}const KMD5::Digest& KMD5::rawDigest(){    finalize();    return m_digest;}void KMD5::rawDigest( KMD5::Digest& bin ){    finalize();    memcpy( bin, m_digest, 16 );}QCString KMD5::hexDigest(){    QCString s(33);    finalize();    sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",            m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],            m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],            m_digest[12], m_digest[13], m_digest[14], m_digest[15]);    return s;}void KMD5::hexDigest(QCString& s){    finalize();    s.resize(33);    sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",            m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],            m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],            m_digest[12], m_digest[13], m_digest[14], m_digest[15]);}QCString KMD5::base64Digest(){    QByteArray ba(16);    finalize();    memcpy(ba.data(), m_digest, 16);    return KCodecs::base64Encode(ba);}void KMD5::init(){    d = 0;    reset();}void KMD5::reset(){    m_finalized = false;    m_count[0] = 0;    m_count[1] = 0;    m_state[0] = 0x67452301;    m_state[1] = 0xefcdab89;    m_state[2] = 0x98badcfe;    m_state[3] = 0x10325476;    memset ( m_buffer, 0, sizeof(*m_buffer));    memset ( m_digest, 0, sizeof(*m_digest));}void KMD5::transform( const unsigned char block[64] ){    Q_UINT32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];    decode (x, block, 64);    //memcpy( x, block, 64 );    Q_ASSERT(!m_finalized);  // not just a user error, since the method is private    /* Round 1 */    FF (a, b, c, d, x[ 0], KMD5_S11, 0xd76aa478); /* 1 */    FF (d, a, b, c, x[ 1], KMD5_S12, 0xe8c7b756); /* 2 */    FF (c, d, a, b, x[ 2], KMD5_S13, 0x242070db); /* 3 */    FF (b, c, d, a, x[ 3], KMD5_S14, 0xc1bdceee); /* 4 */    FF (a, b, c, d, x[ 4], KMD5_S11, 0xf57c0faf); /* 5 */    FF (d, a, b, c, x[ 5], KMD5_S12, 0x4787c62a); /* 6 */    FF (c, d, a, b, x[ 6], KMD5_S13, 0xa8304613); /* 7 */    FF (b, c, d, a, x[ 7], KMD5_S14, 0xfd469501); /* 8 */    FF (a, b, c, d, x[ 8], KMD5_S11, 0x698098d8); /* 9 */    FF (d, a, b, c, x[ 9], KMD5_S12, 0x8b44f7af); /* 10 */    FF (c, d, a, b, x[10], KMD5_S13, 0xffff5bb1); /* 11 */    FF (b, c, d, a, x[11], KMD5_S14, 0x895cd7be); /* 12 */    FF (a, b, c, d, x[12], KMD5_S11, 0x6b901122); /* 13 */    FF (d, a, b, c, x[13], KMD5_S12, 0xfd987193); /* 14 */    FF (c, d, a, b, x[14], KMD5_S13, 0xa679438e); /* 15 */    FF (b, c, d, a, x[15], KMD5_S14, 0x49b40821); /* 16 */    /* Round 2 */    GG (a, b, c, d, x[ 1], KMD5_S21, 0xf61e2562); /* 17 */    GG (d, a, b, c, x[ 6], KMD5_S22, 0xc040b340); /* 18 */    GG (c, d, a, b, x[11], KMD5_S23, 0x265e5a51); /* 19 */    GG (b, c, d, a, x[ 0], KMD5_S24, 0xe9b6c7aa); /* 20 */    GG (a, b, c, d, x[ 5], KMD5_S21, 0xd62f105d); /* 21 */    GG (d, a, b, c, x[10], KMD5_S22,  0x2441453); /* 22 */    GG (c, d, a, b, x[15], KMD5_S23, 0xd8a1e681); /* 23 */    GG (b, c, d, a, x[ 4], KMD5_S24, 0xe7d3fbc8); /* 24 */    GG (a, b, c, d, x[ 9], KMD5_S21, 0x21e1cde6); /* 25 */    GG (d, a, b, c, x[14], KMD5_S22, 0xc33707d6); /* 26 */    GG (c, d, a, b, x[ 3], KMD5_S23, 0xf4d50d87); /* 27 */    GG (b, c, d, a, x[ 8], KMD5_S24, 0x455a14ed); /* 28 */    GG (a, b, c, d, x[13], KMD5_S21, 0xa9e3e905); /* 29 */    GG (d, a, b, c, x[ 2], KMD5_S22, 0xfcefa3f8); /* 30 */    GG (c, d, a, b, x[ 7], KMD5_S23, 0x676f02d9); /* 31 */    GG (b, c, d, a, x[12], KMD5_S24, 0x8d2a4c8a); /* 32 */    /* Round 3 */    HH (a, b, c, d, x[ 5], KMD5_S31, 0xfffa3942); /* 33 */    HH (d, a, b, c, x[ 8], KMD5_S32, 0x8771f681); /* 34 */    HH (c, d, a, b, x[11], KMD5_S33, 0x6d9d6122); /* 35 */    HH (b, c, d, a, x[14], KMD5_S34, 0xfde5380c); /* 36 */    HH (a, b, c, d, x[ 1], KMD5_S31, 0xa4beea44); /* 37 */    HH (d, a, b, c, x[ 4], KMD5_S32, 0x4bdecfa9); /* 38 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?