⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 base64.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:

    i = 0;
    if (d[2] == '=')
    {
        if ((ip0 = decodeBase64Byte(d[0])) > 63)
            return ERROR_INVALID_DATA;
        if ((ip1 = decodeBase64Byte(d[1])) > 63)
            return ERROR_INVALID_DATA;

        if (out_buf)
            out_buf[i] = (ip0 << 2) | (ip1 >> 4);
        i++;
    }
    else if (d[3] == '=')
    {
        if ((ip0 = decodeBase64Byte(d[0])) > 63)
            return ERROR_INVALID_DATA;
        if ((ip1 = decodeBase64Byte(d[1])) > 63)
            return ERROR_INVALID_DATA;
        if ((ip2 = decodeBase64Byte(d[2])) > 63)
            return ERROR_INVALID_DATA;

        if (out_buf)
        {
            out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4);
            out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2);
        }
        i += 2;
    }
    else
    {
        if ((ip0 = decodeBase64Byte(d[0])) > 63)
            return ERROR_INVALID_DATA;
        if ((ip1 = decodeBase64Byte(d[1])) > 63)
            return ERROR_INVALID_DATA;
        if ((ip2 = decodeBase64Byte(d[2])) > 63)
            return ERROR_INVALID_DATA;
        if ((ip3 = decodeBase64Byte(d[3])) > 63)
            return ERROR_INVALID_DATA;

        if (out_buf)
        {
            out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4);
            out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2);
            out_buf[i + 2] = (ip2 << 6) |  ip3;
        }
        i += 3;
    }
    if (len >= 6 && d[4] == '\r' && d[5] == '\n')
        *nextBlock = d + 6;
    else if (len >= 5 && d[4] == '\n')
        *nextBlock = d + 5;
    else if (len >= 4 && d[4])
        *nextBlock = d + 4;
    else
        *nextBlock = NULL;
    *out_len = i;
    return ERROR_SUCCESS;
}

/* Unlike CryptStringToBinaryA, cchString is guaranteed to be the length of the
 * string to convert.
 */
typedef LONG (*StringToBinaryAFunc)(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);

static LONG Base64ToBinaryA(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
    LONG ret = ERROR_SUCCESS;
    const char *nextBlock;
    DWORD outLen = 0;

    nextBlock = pszString;
    while (nextBlock && !ret)
    {
        DWORD len = 0;

        ret = decodeBase64Block(nextBlock, cchString - (nextBlock - pszString),
         &nextBlock, pbBinary ? pbBinary + outLen : NULL, &len);
        if (!ret)
            outLen += len;
        if (cchString - (nextBlock - pszString) <= 0)
            nextBlock = NULL;
    }
    *pcbBinary = outLen;
    if (!ret)
    {
        if (pdwSkip)
            *pdwSkip = 0;
        if (pdwFlags)
            *pdwFlags = CRYPT_STRING_BASE64;
    }
    else if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        if (!pbBinary)
            ret = ERROR_SUCCESS;
    }
    return ret;
}

static LONG Base64WithHeaderAndTrailerToBinaryA(LPCSTR pszString,
 DWORD cchString, LPCSTR header, LPCSTR trailer, BYTE *pbBinary,
 DWORD *pcbBinary, DWORD *pdwSkip)
{
    LONG ret;
    LPCSTR ptr;

    if (cchString > strlen(header) + strlen(trailer)
     && (ptr = strstr(pszString, header)) != NULL)
    {
        LPCSTR trailerSpot = pszString + cchString - strlen(trailer);

        if (pszString[cchString - 1] == '\n')
        {
            cchString--;
            trailerSpot--;
        }
        if (pszString[cchString - 1] == '\r')
        {
            cchString--;
            trailerSpot--;
        }
        if (!strncmp(trailerSpot, trailer, strlen(trailer)))
        {
            if (pdwSkip)
                *pdwSkip = ptr - pszString;
            ptr += strlen(header);
            if (*ptr == '\r') ptr++;
            if (*ptr == '\n') ptr++;
            cchString -= ptr - pszString + strlen(trailer);
            ret = Base64ToBinaryA(ptr, cchString, pbBinary, pcbBinary, NULL,
             NULL);
        }
        else
            ret = ERROR_INVALID_DATA;
    }
    else
        ret = ERROR_INVALID_DATA;
    return ret;
}

static LONG Base64HeaderToBinaryA(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
    LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
     CERT_HEADER, CERT_TRAILER, pbBinary, pcbBinary, pdwSkip);

    if (!ret && pdwFlags)
        *pdwFlags = CRYPT_STRING_BASE64HEADER;
    return ret;
}

static LONG Base64RequestHeaderToBinaryA(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
    LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
     CERT_REQUEST_HEADER, CERT_REQUEST_TRAILER, pbBinary, pcbBinary, pdwSkip);

    if (!ret && pdwFlags)
        *pdwFlags = CRYPT_STRING_BASE64REQUESTHEADER;
    return ret;
}

static LONG Base64X509HeaderToBinaryA(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
    LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
     X509_HEADER, X509_TRAILER, pbBinary, pcbBinary, pdwSkip);

    if (!ret && pdwFlags)
        *pdwFlags = CRYPT_STRING_BASE64X509CRLHEADER;
    return ret;
}

static LONG Base64AnyToBinaryA(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
    LONG ret;

    ret = Base64HeaderToBinaryA(pszString, cchString, pbBinary, pcbBinary,
     pdwSkip, pdwFlags);
    if (ret == ERROR_INVALID_DATA)
        ret = Base64ToBinaryA(pszString, cchString, pbBinary, pcbBinary,
         pdwSkip, pdwFlags);
    return ret;
}

static LONG DecodeBinaryToBinaryA(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
    LONG ret = ERROR_SUCCESS;

    if (*pcbBinary < cchString)
    {
        if (!pbBinary)
            *pcbBinary = cchString;
        else
        {
            ret = ERROR_INSUFFICIENT_BUFFER;
            *pcbBinary = cchString;
        }
    }
    else
    {
        if (cchString)
            memcpy(pbBinary, pszString, cchString);
        *pcbBinary = cchString;
    }
    return ret;
}

static LONG DecodeAnyA(LPCSTR pszString, DWORD cchString,
 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
    LONG ret;

    ret = Base64HeaderToBinaryA(pszString, cchString, pbBinary, pcbBinary,
     pdwSkip, pdwFlags);
    if (ret == ERROR_INVALID_DATA)
        ret = Base64ToBinaryA(pszString, cchString, pbBinary, pcbBinary,
         pdwSkip, pdwFlags);
    if (ret == ERROR_INVALID_DATA)
        ret = DecodeBinaryToBinaryA(pszString, cchString, pbBinary, pcbBinary,
         pdwSkip, pdwFlags);
    return ret;
}

BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
 DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary,
 DWORD *pdwSkip, DWORD *pdwFlags)
{
    StringToBinaryAFunc decoder;
    LONG ret;

    TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_a(pszString),
     cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);

    if (!pszString)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    /* Only the bottom byte contains valid types */
    if (dwFlags & 0xfffffff0)
    {
        SetLastError(ERROR_INVALID_DATA);
        return FALSE;
    }
    switch (dwFlags)
    {
    case CRYPT_STRING_BASE64_ANY:
        decoder = Base64AnyToBinaryA;
        break;
    case CRYPT_STRING_BASE64:
        decoder = Base64ToBinaryA;
        break;
    case CRYPT_STRING_BASE64HEADER:
        decoder = Base64HeaderToBinaryA;
        break;
    case CRYPT_STRING_BASE64REQUESTHEADER:
        decoder = Base64RequestHeaderToBinaryA;
        break;
    case CRYPT_STRING_BASE64X509CRLHEADER:
        decoder = Base64X509HeaderToBinaryA;
        break;
    case CRYPT_STRING_BINARY:
        decoder = DecodeBinaryToBinaryA;
        break;
    case CRYPT_STRING_ANY:
        decoder = DecodeAnyA;
        break;
    case CRYPT_STRING_HEX:
    case CRYPT_STRING_HEXASCII:
    case CRYPT_STRING_HEXADDR:
    case CRYPT_STRING_HEXASCIIADDR:
        FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
        /* fall through */
    default:
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    if (!cchString)
        cchString = strlen(pszString);
    ret = decoder(pszString, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags);
    if (ret)
        SetLastError(ret);
    return (ret == ERROR_SUCCESS) ? TRUE : FALSE;
}

⌨️ 快捷键说明

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