kmdcodec.cpp

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

CPP
1,508
字号
/*   Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>   Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU Lesser General Public License (LGPL)   version 2 as published by the Free Software Foundation.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with this program; if not, write to the Free Software   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.   RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992.   RSA Data Security, Inc. Created 1991. All rights reserved.   The KMD5 class is based on a C++ implementation of   "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by   Mordechai T. Abzug,	Copyright (c) 1995.  This implementation   passes the test-suite as defined in RFC 1321.   The encoding and decoding utilities in KCodecs with the exception of   quoted-printable are based on the java implementation in HTTPClient   package by Ronald Tschal鋜 Copyright (C) 1996-1999.   The quoted-printable codec as described in RFC 2045, section 6.7. is by   Rik Hemsley (C) 2001.   KMD4 class based on the LGPL code of Copyright (C) 2001 Nikos Mavroyanopoulos   The algorithm is due to Ron Rivest.  This code is based on code   written by Colin Plumb in 1993.*/#include <config.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <kdebug.h>#include "kmdcodec.h"#define KMD5_S11 7#define KMD5_S12 12#define KMD5_S13 17#define KMD5_S14 22#define KMD5_S21 5#define KMD5_S22 9#define KMD5_S23 14#define KMD5_S24 20#define KMD5_S31 4#define KMD5_S32 11#define KMD5_S33 16#define KMD5_S34 23#define KMD5_S41 6#define KMD5_S42 10#define KMD5_S43 15#define KMD5_S44 21const char KCodecs::Base64EncMap[64] ={  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,  0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,  0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,  0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,  0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F};const char KCodecs::Base64DecMap[128] ={  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,  0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,  0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,  0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00};const char KCodecs::UUEncMap[64] ={  0x60, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,  0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,  0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F};const char KCodecs::UUDecMap[128] ={  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};const char KCodecs::hexChars[16] ={  '0', '1', '2', '3', '4', '5', '6', '7',  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};const unsigned int KCodecs::maxQPLineLength = 70;/******************************** KCodecs ********************************/// strchr(3) for broken systems.static int rikFindChar(register const char * _s, const char c){  register const char * s = _s;  while (true)  {    if ((0 == *s) || (c == *s)) break; ++s;    if ((0 == *s) || (c == *s)) break; ++s;    if ((0 == *s) || (c == *s)) break; ++s;    if ((0 == *s) || (c == *s)) break; ++s;  }  return s - _s;}QCString KCodecs::quotedPrintableEncode(const QByteArray& in, bool useCRLF){  QByteArray out;  quotedPrintableEncode (in, out, useCRLF);  return QCString (out.data(), out.size()+1);}QCString KCodecs::quotedPrintableEncode(const QCString& str, bool useCRLF){  if (str.isEmpty())    return "";  QByteArray in (str.length());  memcpy (in.data(), str.data(), str.length());  return quotedPrintableEncode(in, useCRLF);}void KCodecs::quotedPrintableEncode(const QByteArray& in, QByteArray& out, bool useCRLF){  out.resize (0);  if (in.isEmpty())    return;  char *cursor;  const char *data;  unsigned int lineLength;  unsigned int pos;  const unsigned int length = in.size();  const unsigned int end = length - 1;  // Reasonable guess for output size when we're encoding  // mostly-ASCII data. It doesn't really matter, because  // the underlying allocation routines are quite efficient,  // but it's nice to have 0 allocations in many cases.  out.resize ((length*12)/10);  cursor = out.data();  data = in.data();  lineLength = 0;  pos = 0;  for (unsigned int i = 0; i < length; i++)  {    unsigned char c (data[i]);    // check if we have to enlarge the output buffer, use    // a safety margin of 16 byte    pos = cursor-out.data();    if (out.size()-pos < 16) {      out.resize(out.size()+4096);      cursor = out.data()+pos;    }    // Plain ASCII chars just go straight out.    if ((c >= 33) && (c <= 126) && ('=' != c))    {      *cursor++ = c;      ++lineLength;    }    // Spaces need some thought. We have to encode them at eol (or eof).    else if (' ' == c)    {      if        (         (i >= length)         ||         ((i < end) && ((useCRLF && ('\r' == data[i + 1]) && ('\n' == data[i + 2]))                        ||                        (!useCRLF && ('\n' == data[i + 1]))))        )      {        *cursor++ = '=';        *cursor++ = '2';        *cursor++ = '0';        lineLength += 3;      }      else      {        *cursor++ = ' ';        ++lineLength;      }    }    // If we find a line break, just let it through.    else if ((useCRLF && ('\r' == c) && (i < end) && ('\n' == data[i + 1])) ||             (!useCRLF && ('\n' == c)))    {      lineLength = 0;      if (useCRLF) {        *cursor++ = '\r';        *cursor++ = '\n';        ++i;      } else {        *cursor++ = '\n';      }    }    // Anything else is converted to =XX.    else    {      *cursor++ = '=';      *cursor++ = hexChars[c / 16];      *cursor++ = hexChars[c % 16];      lineLength += 3;    }    // If we're approaching the maximum line length, do a soft line break.    if ((lineLength > maxQPLineLength) && (i < end))    {      if (useCRLF) {        *cursor++ = '=';        *cursor++ = '\r';        *cursor++ = '\n';      } else {        *cursor++ = '=';        *cursor++ = '\n';      }      lineLength = 0;    }  }  out.truncate(cursor - out.data());}QCString KCodecs::quotedPrintableDecode(const QByteArray & in){  QByteArray out;  quotedPrintableDecode (in, out);  return QCString (out.data(), out.size()+1);}QCString KCodecs::quotedPrintableDecode(const QCString & str){  if (str.isEmpty())    return "";  QByteArray in (str.length());  memcpy (in.data(), str.data(), str.length());  return quotedPrintableDecode (in);}void KCodecs::quotedPrintableDecode(const QByteArray& in, QByteArray& out){  // clear out the output buffer  out.resize (0);  if (in.isEmpty())      return;  char *cursor;  const char *data;  const unsigned int length = in.size();  data = in.data();  out.resize (length);  cursor = out.data();  for (unsigned int i = 0; i < length; i++)  {    char c(in[i]);    if ('=' == c)    {      if (i < length - 2)      {        char c1 = in[i + 1];        char c2 = in[i + 2];        if (('\n' == c1) || ('\r' == c1 && '\n' == c2))        {          // Soft line break. No output.          if ('\r' == c1)            i += 2;        // CRLF line breaks          else            i += 1;        }        else        {          // =XX encoded byte.          int hexChar0 = rikFindChar(hexChars, c1);          int hexChar1 = rikFindChar(hexChars, c2);          if (hexChar0 < 16 && hexChar1 < 16)          {            *cursor++ = char((hexChar0 * 16) | hexChar1);            i += 2;          }        }      }    }    else    {      *cursor++ = c;    }  }  out.truncate(cursor - out.data());}QCString KCodecs::base64Encode( const QCString& str, bool insertLFs ){    if ( str.isEmpty() )        return "";    QByteArray in (str.length());    memcpy( in.data(), str.data(), str.length() );    return base64Encode( in, insertLFs );}QCString KCodecs::base64Encode( const QByteArray& in, bool insertLFs ){    QByteArray out;    base64Encode( in, out, insertLFs );    return QCString( out.data(), out.size()+1 );}void KCodecs::base64Encode( const QByteArray& in, QByteArray& out,                            bool insertLFs ){    // clear out the output buffer    out.resize (0);    if ( in.isEmpty() )        return;    unsigned int sidx = 0;    unsigned int didx = 0;    const char* data = in.data();    const unsigned int len = in.size();    unsigned int out_len = ((len+2)/3)*4;    // Deal with the 76 characters or less per    // line limit specified in RFC 2045 on a    // pre request basis.    insertLFs = (insertLFs && out_len > 76);    if ( insertLFs )      out_len += ((out_len-1)/76);    int count = 0;    out.resize( out_len );    // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion    if ( len > 1 )    {        while (sidx < len-2)        {            if ( insertLFs )            {                if ( count && (count%76) == 0 )                    out[didx++] = '\n';                count += 4;            }            out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];            out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |                                       (data[sidx] << 4) & 077];            out[didx++] = Base64EncMap[(data[sidx+2] >> 6) & 003 |                                       (data[sidx+1] << 2) & 077];            out[didx++] = Base64EncMap[data[sidx+2] & 077];            sidx += 3;        }    }    if (sidx < len)    {        if ( insertLFs && (count > 0) && (count%76) == 0 )           out[didx++] = '\n';        out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];        if (sidx < len-1)        {            out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |                                       (data[sidx] << 4) & 077];            out[didx++] = Base64EncMap[(data[sidx+1] << 2) & 077];        }        else        {            out[didx++] = Base64EncMap[(data[sidx] << 4) & 077];        }    }    // Add padding    while (didx < out.size())    {        out[didx] = '=';        didx++;    }}QCString KCodecs::base64Decode( const QCString& str ){    if ( str.isEmpty() )        return "";    QByteArray in( str.length() );    memcpy( in.data(), str.data(), str.length() );    return base64Decode( in );}QCString KCodecs::base64Decode( const QByteArray& in ){    QByteArray out;    base64Decode( in, out );    return QCString( out.data(), out.size()+1 );}void KCodecs::base64Decode( const QByteArray& in, QByteArray& out ){    out.resize(0);    if ( in.isEmpty() )        return;    unsigned int count = 0;    unsigned int len = in.size(), tail = len;    const char* data = in.data();    // Deal with possible *nix "BEGIN" marker!!    while ( count < len && (data[count] == '\n' || data[count] == '\r' ||            data[count] == '\t' || data[count] == ' ') )        count++;    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;        tail = (len -= count);    }    // Find the tail end of the actual encoded data even if    // there is/are trailing CR and/or LF.    while ( data[tail-1] == '=' || data[tail-1] == '\n' ||            data[tail-1] == '\r' )        if ( data[--tail] != '=' ) len = tail;    unsigned int outIdx = 0;    out.resize( (count=len) );

⌨️ 快捷键说明

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