cht電腦資訊Linux
adm Find login register

請問一下,C的程式要怎麼寫,關於 md5 及 base64

candyz
1 請問一下,C的程式要怎麼寫,關於 md5 及 base64
Promote 0 Bookmark 02007-12-18quote  

我不會寫 C ...XD

想問一下,在 php 裡,是下這樣的指令,主要就是下 md5 後,再 pack 後,再 base64 encode 

print base64_encode(pack('H*',md5(''testabc)))."\n";

如果要改成用 C 寫,要怎麼寫? 

edited: 2
eliu
2
Promote 0 Bookmark 02007-12-11quote  

剛才 man MD5 現學現賣,至於 base64 我就不會了。

cc -g t.c -lssl 

#include <openssl/md5.h>
#include <stdio.h>

main()
{

  unsigned char *out = MD5("testabc", strlen("testabc"), NULL);

  int i;
  for(i=0; i < MD5_DIGEST_LENGTH; i++)
   printf("%02X", out[i]);
  puts("");
}

edited: 2
本人已不在此站活動
3
Promote 0 Bookmark 02007-12-11quote  

C 忘光光!:Q

我會一點 ruby: 

#!/usr/bin/env ruby
require 'digest/md5'
require 'base64'
md = Digest::MD5.new
md << "testabc"
Base64.b64encode(md.digest)

看起來好像不如用 php 了!吐舌頭

qrtt1
4 可以偷php的來用啊:P
Promote 2 Bookmark 12008-02-14quote  

 /*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2007 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Jim Winstead <jimw@php.net>                                  |
   +----------------------------------------------------------------------+
 */
/* $Id: base64.c,v 1.43.2.2.2.3 2007/07/21 01:24:26 jani Exp $ */

 

 

 ======================================================

// php-5.2.5/ext/standard/base64.c
 

#include<stdio.h>
#include<stdlib.h>

/* {{{ */
static const char base64_table[] =
    { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
      'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
      'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
    };

static const char base64_pad = '=';

static const short base64_reverse_table[256] = {
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
    -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
    -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
};
/* }}} */


/*PHPAPI*/ unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length)
{
    const unsigned char *current = str;
    unsigned char *p;
    unsigned char *result;

    if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
        if (ret_length != NULL) {
            *ret_length = 0;
        }
        return NULL;
    }

    // safe_emalloc 在 Zend 的 alloc.c 內, 小複雜了我懶 orz

   // 如果有 leak 俺不負責 XD

   // result = (unsigned char *)safe_emalloc(((length + 2) / 3) * 4, sizeof(char), 1);
    result = (unsigned char *) malloc(((length + 2) / 3) * 4 * sizeof(char));
    p = result;

    while (length > 2) { /* keep going until we have less than 24 bits */
        *p++ = base64_table[current[0] >> 2];
        *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
        *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
        *p++ = base64_table[current[2] & 0x3f];

        current += 3;
        length -= 3; /* we just handle 3 octets of data */
    }

    /* now deal with the tail end of things */
    if (length != 0) {
        *p++ = base64_table[current[0] >> 2];
        if (length > 1) {
            *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
            *p++ = base64_table[(current[1] & 0x0f) << 2];
            *p++ = base64_pad;
        } else {
            *p++ = base64_table[(current[0] & 0x03) << 4];
            *p++ = base64_pad;
            *p++ = base64_pad;
        }
    }
    if (ret_length != NULL) {
        *ret_length = (int)(p - result);
    }
    *p = '\0';
    return result;
}


int main(void){
//unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length)

    const unsigned char *str = "qrtt1";
    int ret_len = 0;

    unsigned char *xd = php_base64_encode(str, 5, &ret_len);
    printf("%s\n", xd);

    free(xd);

}
 

edited: 1
Firedragen
5 base64.c
Promote 1 Bookmark 02008-03-08quote  

這是我手上目前使用的 base64 工具,用起來是 ok 的,可以試試看

 

/*
 * base64.h
 *
 * 本檔案是基於
 * base64.c
 * Base64 encoding/decoding command line filter
 * Copyright (c) 2002 Matthias Gaertner 29.06.2002
 * 所改寫的base64編碼函式。
 * Rewrite encodeB64 by Jao Hao Chieh (05.06.2005)
 * Update decodeB64 function at (05.07.2006)
 * 原始程式為符合GNU開放源碼之base64編碼/解碼程式,
 * 這裡精簡為方便使用的標頭檔。
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * 函式說明:
 * char *encodeB64(char* fileName) - 將檔案路徑傳入,編碼後傳回檔案之base64字串
 *
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include "general.h"

#ifndef _BASE64_H_
#define _BASE64_H_

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define ENCODE_BUFFER_SIZE_IN (8192*18)
#define ENCODE_BUFFER_SIZE_OUT (8192*36)
#define DECODE_BUFFER_SIZE_IN (8192*24)
#define DECODE_BUFFER_SIZE_OUT (8192*18)

static int g_fUseCRLF= FALSE;
static unsigned int g_nCharsPerLine = 64;
static const char* to_b64 =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* encodeB64(char* fileName);

/**
 * 將檔案編碼為base64字串
 *
 * @param fileName 檔案路徑字串
 * @return pbBufferOut 經編碼後之字串內容
 **/

char* encodeB64(char* fileName) {
    FILE *g_fIn = fopen(fileName, "rb");

    char *pbBufferIn = (char*) malloc( ENCODE_BUFFER_SIZE_IN);
    char *pbBufferOut = (char*) malloc( ENCODE_BUFFER_SIZE_OUT);
    for (;;) {
        unsigned long nDiv = 0;
        unsigned long nRem = 0;
        unsigned long nChars = 0;
        unsigned char* pIn = (unsigned char*) pbBufferIn;
        unsigned int nOut = 0;
        size_t nWritten = 0;

        size_t nRead = fread( (void*)pIn, 1, ENCODE_BUFFER_SIZE_IN, g_fIn);

        nDiv = ((unsigned long)nRead) / 3;
        nRem = ((unsigned long)nRead) % 3;
        nChars = 0;

        while (nDiv > 0) {
            pbBufferOut[nOut+0] = to_b64[ (pIn[0] >> 2) & 0x3f];
            pbBufferOut[nOut+1] = to_b64[((pIn[0] << 4) & 0x30) + ((pIn[1] >> 4) & 0xf)];
            pbBufferOut[nOut+2] = to_b64[((pIn[1] << 2) & 0x3c) + ((pIn[2] >> 6) & 0x3)];
            pbBufferOut[nOut+3] = to_b64[ pIn[2] & 0x3f];
            pIn += 3;
            nOut += 4;
            nDiv--;
            nChars += 4;
        }

        switch (nRem) {
            case 2:
                pbBufferOut[nOut+0] = to_b64[ (pIn[0] >> 2) & 0x3f];
                pbBufferOut[nOut+1] = to_b64[((pIn[0] << 4) & 0x30) + ((pIn[1] >> 4) & 0xf)];
                pbBufferOut[nOut+2] = to_b64[ (pIn[1] << 2) & 0x3c];
                pbBufferOut[nOut+3] = '=';
                nOut += 4;
                nChars += 4;
                if (nChars >= g_nCharsPerLine && g_nCharsPerLine != 0) {
                    nChars = 0;
                    if (g_fUseCRLF) {
                        pbBufferOut[nOut++] = '\r';
                    }
                    pbBufferOut[nOut++] = '\n';
                }
                break;
            case 1:
                pbBufferOut[nOut+0] = to_b64[ (pIn[0] >> 2) & 0x3f];
                pbBufferOut[nOut+1] = to_b64[ (pIn[0] << 4) & 0x30];
                pbBufferOut[nOut+2] = '=';
                pbBufferOut[nOut+3] = '=';
                nOut += 4;
                nChars += 4;
                if (nChars >= g_nCharsPerLine && g_nCharsPerLine != 0) {
                    nChars = 0;
                    if (g_fUseCRLF) {
                        pbBufferOut[nOut++] = '\r';
                    }
                    pbBufferOut[nOut++] = '\n';
                }
                break;
        }

        if (nRem > 0 || feof(g_fIn) ) {
            if (nChars > 0) {
                nChars = 0;
                if (g_fUseCRLF) {
                    pbBufferOut[nOut++] = '\r';
                }
                pbBufferOut[nOut++] = '\n';
            }
        }

        if (nRem > 0 || feof(g_fIn) ) {
            break;
        }
    }
    fclose(g_fIn);
    free(pbBufferIn);
    return pbBufferOut;
}

/**
 * 將base64字串解碼為指定檔名之檔案
 *
 * @param fileName 檔案路徑字串
 * @return pbBufferOut 經編碼後之字串內容
 **/
int decodeB64(char *filename, char *encBuf) {
    FILE *g_fOut = fopen(filename, "wb");
    int nIn = 0;
    int bufLength = strlen(encBuf);
    int z = 0; // 0 Normal, 1 skip MIME separator (---) to end of line
    char c = '\0';
    unsigned char data[3];
    unsigned int nData = 0;

    for (;; nIn++) {
        unsigned char bits = 'z';
        if (nIn >= bufLength) {
            break;
        }
        c = encBuf[nIn];
        if (z > 0) {
            if (c == '\n') {
                z = 0;
            }
        } else if (c >= 'A' && c <= 'Z') {
            bits = (unsigned char) (c - 'A');
        } else if (c >= 'a' && c <= 'z') {
            bits = (unsigned char) (c - 'a' + (char)26);
        } else if (c >= '0' && c <= '9') {
            bits = (unsigned char) (c - '0' + (char)52);
        } else if (c == '+') {
            bits = (unsigned char) 62;
        } else if (c == '/') {
            bits = (unsigned char) 63;
        } else if (c == '-') {
            z = 1;
        } else if (c == '=') {
            break;
        } else {
            bits = (unsigned char) 'y';
        }

        if (bits < (unsigned char) 64 ) {
            switch (nData++) {
                case 0:
                    data[0] = (bits << 2) & 0xfc;
                    break;
                case 1:
                    data[0] |= (bits >> 4) & 0x03;
                    data[1] = (bits << 4) & 0xf0;
                    break;
                case 2:
                    data[1] |= (bits >> 2) & 0x0f;
                    data[2] = (bits << 6) & 0xc0;
                    break;
                case 3:
                    data[2] |= bits & 0x3f;
                    break;
            }

            if (nData == 4) {
                size_t n = fwrite( (void*)data, 1, 3, g_fOut);
                if (ferror(g_fOut) || n < 3) {
                    printf("error 202: Can not write file.\n");
                    break;
                }
                nData = 0;
            }
        }
    }

    if (nData > 0) {
        if (nData == 1) {
            printf("error 212: May not Base64 format.\n");
        } else {
            size_t n = fwrite( (void*)data, 1, nData-1, g_fOut);
            if (ferror(g_fOut) || n < (nData-1)) {
                printf("error 216: Can not write file.\n");
            }
        }
    }
    fclose(g_fOut);
    return 0;
}

/**
 * 將base64字串解碼為指定檔名之檔案,並以附加方式寫入該檔案
 *
 * @param fileName 檔案路徑字串
 * @return pbBufferOut 經編碼後之字串內容
 **/
int decodeB64a(char *filename, char * encBuf) {
    FILE *g_fOut = fopen(filename, "ab");
    int nIn = 0;
    int bufLength = strlen(encBuf);
    int z = 0; // 0 Normal, 1 skip MIME separator (---) to end of line
    char c = '\0';
    unsigned char data[3];
    unsigned int nData = 0;

    for (;; nIn++) {
        unsigned char bits = 'z';
        if (nIn >= bufLength) {
            break;
        }
        c = encBuf[nIn];
        if (z > 0) {
            if (c == '\n') {
                z = 0;
            }
        } else if (c >= 'A' && c <= 'Z') {
            bits = (unsigned char) (c - 'A');
        } else if (c >= 'a' && c <= 'z') {
            bits = (unsigned char) (c - 'a' + (char)26);
        } else if (c >= '0' && c <= '9') {
            bits = (unsigned char) (c - '0' + (char)52);
        } else if (c == '+') {
            bits = (unsigned char) 62;
        } else if (c == '/') {
            bits = (unsigned char) 63;
        } else if (c == '-') {
            z = 1;
        } else if (c == '=') {
            break;
        } else {
            bits = (unsigned char) 'y';
        }

        if (bits < (unsigned char) 64 ) {
            switch (nData++) {
                case 0:
                    data[0] = (bits << 2) & 0xfc;
                    break;
                case 1:
                    data[0] |= (bits >> 4) & 0x03;
                    data[1] = (bits << 4) & 0xf0;
                    break;
                case 2:
                    data[1] |= (bits >> 2) & 0x0f;
                    data[2] = (bits << 6) & 0xc0;
                    break;
                case 3:
                    data[2] |= bits & 0x3f;
                    break;
            }

            if (nData == 4) {
                size_t n = fwrite( (void*)data, 1, 3, g_fOut);
                if (ferror(g_fOut) || n < 3) {
                    printf("error 202: Can not write file.\n");
                    break;
                }
                nData = 0;
            }
        }
    }

    if (nData > 0) {
        if (nData == 1) {
            printf("error 212: May not Base64 format.\n");
        } else {
            size_t n = fwrite( (void*)data, 1, nData-1, g_fOut);
            if (ferror(g_fOut) || n < (nData-1)) {
                printf("error 216: Can not write file.\n");
            }
        }
    }
    fclose(g_fOut);
    return 0;
}

/**
 * 將base64字串解碼並填入指定字串
 *
 * @param context 欲寫入之字串
 * @return pbBufferOut 經編碼後之字串內容
 **/
int decodeB64c(char *filename, char * encBuf) {
    FILE *g_fOut = fopen(filename, "ab");
    int nIn = 0;
    int bufLength = strlen(encBuf);
    int z = 0; // 0 Normal, 1 skip MIME separator (---) to end of line
    char c = '\0';
    unsigned char data[3];
    unsigned int nData = 0;

    for (;; nIn++) {
        unsigned char bits = 'z';
        if (nIn >= bufLength) {
            break;
        }
        c = encBuf[nIn];
        if (z > 0) {
            if (c == '\n') {
                z = 0;
            }
        } else if (c >= 'A' && c <= 'Z') {
            bits = (unsigned char) (c - 'A');
        } else if (c >= 'a' && c <= 'z') {
            bits = (unsigned char) (c - 'a' + (char)26);
        } else if (c >= '0' && c <= '9') {
            bits = (unsigned char) (c - '0' + (char)52);
        } else if (c == '+') {
            bits = (unsigned char) 62;
        } else if (c == '/') {
            bits = (unsigned char) 63;
        } else if (c == '-') {
            z = 1;
        } else if (c == '=') {
            break;
        } else {
            bits = (unsigned char) 'y';
        }

        if (bits < (unsigned char) 64 ) {
            switch (nData++) {
                case 0:
                    data[0] = (bits << 2) & 0xfc;
                    break;
                case 1:
                    data[0] |= (bits >> 4) & 0x03;
                    data[1] = (bits << 4) & 0xf0;
                    break;
                case 2:
                    data[1] |= (bits >> 2) & 0x0f;
                    data[2] = (bits << 6) & 0xc0;
                    break;
                case 3:
                    data[2] |= bits & 0x3f;
                    break;
            }

            if (nData == 4) {
                size_t n = fwrite( (void*)data, 1, 3, g_fOut);
                if (ferror(g_fOut) || n < 3) {
                    printf("error 202: Can not write file.\n");
                    break;
                }
                nData = 0;
            }
        }
    }

    if (nData > 0) {
        if (nData == 1) {
            printf("error 212: May not Base64 format.\n");
        } else {
            size_t n = fwrite( (void*)data, 1, nData-1, g_fOut);
            if (ferror(g_fOut) || n < (nData-1)) {
                printf("error 216: Can not write file.\n");
            }
        }
    }
    fclose(g_fOut);
    return 0;
}
#endif //_BASE64_H_
 

carl_tw
6
Promote 0 Bookmark 02008-05-04quote  

沒有想到 MD5 用 C 寫起來竟是如此簡單,學起來了。

CC: PHP Ruby
cht電腦資訊Linux
adm Find login register
views:25577