0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【安全算法之base64】base64加解密的C語言源碼實(shí)現(xiàn)

嵌入式物聯(lián)網(wǎng)開發(fā) ? 來源:嵌入式物聯(lián)網(wǎng)開發(fā) ? 作者:嵌入式物聯(lián)網(wǎng)開發(fā) ? 2022-09-18 09:31 ? 次閱讀

? 最近,有項(xiàng)目中需要用到base64的加解密,所以用C語言實(shí)現(xiàn)了一遍,測試效果還不錯(cuò),代碼量和RAM消耗都比較低,可以提供給大家參考下。

#include 
#include 
#include "base64.h"

static uint8_t get_index_from_char(char c)
{
    if ((c >= 'A') && (c <= 'Z'))           return (c - 'A');
    else if ((c >= 'a') && (c <= 'z'))      return (c - 'a' + 26);
    else if ((c >= '0') && (c <= '9'))      return (c - '0' + 52);
    else if (c == '+')                      return 62;
    else if (c == '/')                      return 63;
    else if (c == '=')                      return 64;
    else if ((c == 'r') || (c == 'n'))    return 254;
    else                                    return 255;
}

static char get_char_from_index(uint8_t i)
{
    if ((i >= 0) && (i <= 25))              return (i + 'A');
    else if ((i >= 26) && (i <= 51))        return (i - 26 + 'a');
    else if ((i >= 52) && (i <= 61))        return (i - 52 + '0');
    else if (i == 62)                       return '+';
    else if (i == 63)                       return '/';
    else                                    return '=';
}

int base64_encode(const uint8_t *in, uint16_t in_len, char *out)
{
    int i;
    uint32_t tmp = 0;
    uint16_t out_len = 0;
    uint16_t left = in_len;

    if ((!in) || (!out)) {
        //invalid parameter
        return BASE64_ERROR;
    }

    for (i = 0; i < in_len;) {
        if (left >= 3) {
            tmp = in[i];
            tmp = (tmp << 8) + in[i+1];
            tmp = (tmp << 8) + in[i+2];
            out[out_len++] = get_char_from_index((tmp & 0x00FC0000) >> 18);
            out[out_len++] = get_char_from_index((tmp & 0x0003F000) >> 12);
            out[out_len++] = get_char_from_index((tmp & 0x00000FC0) >> 6);
            out[out_len++] = get_char_from_index(tmp & 0x0000003F);
            left -= 3;
            i += 3;
        } else {
            break;
        }
    }

    if (left == 2) {
        tmp = in[i];
        tmp = (tmp << 8) + in[i+1];
        out[out_len++] = get_char_from_index((tmp & 0x0000FC00) >> 10);
        out[out_len++] = get_char_from_index((tmp & 0x000003F0) >> 4);
        out[out_len++] = get_char_from_index((tmp & 0x0000000F) << 2);
        out[out_len++] = get_char_from_index(64);
    } else if (left == 1) {
        tmp = in[i];
        out[out_len++] = get_char_from_index((tmp & 0x000000FC) >> 2);
        out[out_len++] = get_char_from_index((tmp & 0x00000003) << 4);
        out[out_len++] = get_char_from_index(64);
        out[out_len++] = get_char_from_index(64);
    }

    out[out_len] = '';

    return BASE64_SUCCESS;
}

int base64_decode(const char *in, uint8_t *out, uint16_t *out_len)
{
    uint16_t i = 0, cnt = 0;
    uint8_t c, in_data_cnt;
    bool error_msg = false;
    uint32_t tmp = 0;

    if ((!in) || (!out) || (!out_len)) {
        //invalid parameter
        return BASE64_ERROR;
    }

    in_data_cnt = 0;
    while (in[i] != '') {
        c = get_index_from_char(in[i++]);
        if (c == 255) {
            //MSG_PRINTF(LOG_ERR, "INVALID MESSAGE CODEn");
            return BASE64_ERR_BASE64_BAD_MSG;
        } else if (c == 254) {
            continue;           // Carriage return or newline feed, skip
        } else if (c == 64) {
            break;              // Meet '=', break
        }

        tmp = (tmp << 6) | c;
        if (++in_data_cnt == 4) {
            out[cnt++] = (uint8_t)((tmp >> 16) & 0xFF);
            out[cnt++] = (uint8_t)((tmp >> 8) & 0xFF);
            out[cnt++] = (uint8_t)(tmp & 0xFF);
            in_data_cnt = 0;
            tmp = 0;
        }
    }

    // Meet '=' or ''
    if (in_data_cnt == 3) {          // 3 chars before '=', encoded msg like xxx= OR
        tmp = (tmp << 6);           // 3 chars before '', encoded msg like xxx, considered '=' omitted
        out[cnt++] = (uint8_t)((tmp >> 16) & 0xFF);
        out[cnt++] = (uint8_t)((tmp >> 8) & 0xFF);
    } else if (in_data_cnt == 2) {   // 2 chars before '=', encoded msg like xx== OR
        tmp = (tmp << 6);           // 2 chars before '', encoded msg like xx, considered '=' omitted
        tmp = (tmp << 6);
        out[cnt++] = (uint8_t)((tmp >> 16) & 0xFF);
    } else if (in_data_cnt != 0) {
        error_msg = true;           // Warn that the message format is wrong, but we tried our best to decode
    }

    *out_len = cnt;

    return (error_msg ? BASE64_ERROR : BASE64_SUCCESS);
}
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

簡單寫了一個(gè)測試demo,有興趣的可以一起看下。


#include 
#include 

#include "base64.h"
#include "convert.h"

int log_hexdump(const char *title, const unsigned char *data, int len)
{
    char str[160], octet[10];
    int ofs, i, k, d;
    const unsigned char *buf = (const unsigned char *)data;
    const char dimm[] = "+------------------------------------------------------------------------------+";

    printf("%s (%d bytes):rn", title, len);
    printf("%srn", dimm);
    printf("| Offset  : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   0123456789ABCDEF |rn");
    printf("%srn", dimm);

    for (ofs = 0; ofs < (int)len; ofs += 16) {
        d = snprintf( str, sizeof(str), "| %08X: ", ofs );

        for (i = 0; i < 16; i++) {
            if ((i + ofs) < (int)len) {
                snprintf( octet, sizeof(octet), "%02X ", buf[ofs + i] );
            } else {
                snprintf( octet, sizeof(octet), "   " );
            }

            d += snprintf( &str[d], sizeof(str) - d, "%s", octet );
        }
        d += snprintf( &str[d], sizeof(str) - d, "  " );
        k = d;

        for (i = 0; i < 16; i++) {
            if ((i + ofs) < (int)len) {
                str[k++] = (0x20 <= (buf[ofs + i]) &&  (buf[ofs + i]) <= 0x7E) ? buf[ofs + i] : '.';
            } else {
                str[k++] = ' ';
            }
        }

        str[k] = '';
        printf("%s |rn", str);
    }

    printf("%srn", dimm);

    return 0;
}

int main(int argc, const char *argv[])
{
	const char *data = "C1D0F8FB4958670DBA40AB1F3752EF0D";
	char base64_enc_calc[128] = {0};
	char base64_enc_exp[128] = "QzFEMEY4RkI0OTU4NjcwREJBNDBBQjFGMzc1MkVGMEQ=";
	const char *p_calc = data;
    uint8_t base64_dec_calc[128];
    uint16_t base64_dec_len = 0;
    int ret;

	if (argc > 1) {
		p_calc = argv[1];
	}

    ret = base64_encode((const uint8_t *)p_calc, strlen(p_calc), base64_enc_calc);

	if (!ret && !strcmp(base64_enc_calc, base64_enc_exp)) {
        printf("base64_enc_calc: %sn", base64_enc_calc);
		printf("BASE64 encryption test OKn");
	} else {
		printf("base64_enc_calc: %sn", base64_enc_calc);
        printf("base64_enc_exp : %sn", base64_enc_exp);
		printf("BASE64 encryption test FAILn");
	}

    ret = base64_decode(base64_enc_calc, base64_dec_calc, &base64_dec_len);
    printf("ret: %dn", ret);
    if (!ret && !strcmp((char *)base64_dec_calc, p_calc)) {
        printf("base64_dec_calc: %sn", base64_dec_calc);
        printf("BASE64 decryption test OKn");
    } else {
        printf("base64_dec_calc: %sn", base64_dec_calc);
        printf("base64_org_data: %sn", p_calc);
        printf("BASE64 decryption test FAILn");
    }

	return 0;
}
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

測試結(jié)果,還挺正常的。

recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$
recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$ ./build.sh
gcc base64.c test.c ../../utils/convert.c -I../../utils -Wall -Werror -o test
recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$
recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$ ./test
base64_enc_calc: QzFEMEY4RkI0OTU4NjcwREJBNDBBQjFGMzc1MkVGMEQ=
BASE64 encryption test OK
ret: 0
base64_dec_calc: C1D0F8FB4958670DBA40AB1F3752EF0D
BASE64 decryption test OK




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • RAM
    RAM
    +關(guān)注

    關(guān)注

    8

    文章

    1369

    瀏覽量

    114754
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7605

    瀏覽量

    137000
  • 加解密
    +關(guān)注

    關(guān)注

    0

    文章

    18

    瀏覽量

    6537
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用base64存儲(chǔ)圖片的優(yōu)勢與劣勢

    優(yōu)勢 兼容性和跨平臺(tái)性 : Base64編碼的字符串是純文本格式,這意味著它們可以在任何支持ASCII文本的環(huán)境中使用,包括不同的操作系統(tǒng)和編程語言。這種跨平臺(tái)性使得Base64編碼的圖片可以輕松
    的頭像 發(fā)表于 11-10 14:25 ?833次閱讀

    base64在前端開發(fā)中的應(yīng)用

    Base64是一種編碼方法,用于將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為ASCII字符串。這種編碼方式在前端開發(fā)中有著廣泛的應(yīng)用,尤其是在數(shù)據(jù)傳輸和存儲(chǔ)方面。 1. Base64編碼的基本概念 Base64編碼是一種
    的頭像 發(fā)表于 11-10 14:24 ?556次閱讀

    如何優(yōu)化base64編碼的性能

    產(chǎn)生影響,特別是在處理大量數(shù)據(jù)時(shí)。以下是一些優(yōu)化Base64編碼性能的方法: 1. 選擇合適的庫和算法 使用高效的庫 :不同的編程語言和庫在Base64編碼和解碼方面有不同的性能表現(xiàn)。
    的頭像 發(fā)表于 11-10 14:17 ?844次閱讀

    base64與URL編碼的區(qū)別和聯(lián)系

    在數(shù)字時(shí)代,數(shù)據(jù)的傳輸和存儲(chǔ)變得尤為重要。為了確保數(shù)據(jù)在不同系統(tǒng)和平臺(tái)之間能夠正確、安全地傳輸,我們需要對(duì)數(shù)據(jù)進(jìn)行編碼。Base64和URL編碼是兩種廣泛使用的編碼技術(shù),它們各自有不同的應(yīng)用場
    的頭像 發(fā)表于 11-10 11:11 ?547次閱讀

    base64在Web開發(fā)中的作用

    一種解決方案,可以將這些二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為ASCII字符串,從而實(shí)現(xiàn)在Web環(huán)境中的無縫傳輸和存儲(chǔ)。 Base64編碼原理 Base64編碼是一種基于64個(gè)可打印字符的編碼方法,包括大寫
    的頭像 發(fā)表于 11-10 11:07 ?394次閱讀

    base64安全性及其應(yīng)用場景

    Base64是一種編碼方法,用于將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為ASCII字符串。它廣泛應(yīng)用于網(wǎng)絡(luò)傳輸、數(shù)據(jù)存儲(chǔ)和文件編碼等領(lǐng)域。然而,Base64編碼并不是一種加密方法,因此其安全性有限。 1. Base
    的頭像 發(fā)表于 11-10 10:59 ?618次閱讀

    base64字符串轉(zhuǎn)換為二進(jìn)制文件

    一些編程知識(shí)。以下是將Base64字符串轉(zhuǎn)換為二進(jìn)制文件的一般步驟,以及一個(gè)簡單的Python示例代碼。 步驟: 獲取Base64字符串 :首先,你需要有一個(gè)Base64編碼的字符串。 解碼B
    的頭像 發(fā)表于 11-10 10:55 ?1231次閱讀

    如何使用base64處理圖像數(shù)據(jù)

    Base64是一種編碼方法,可以將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為ASCII字符集的文本格式。這種編碼方式常用于在不支持二進(jìn)制數(shù)據(jù)的系統(tǒng)之間傳輸圖像數(shù)據(jù),例如在電子郵件、網(wǎng)頁或配置文件中。 1. 理解Base64
    的頭像 發(fā)表于 11-10 10:51 ?685次閱讀

    base64在數(shù)據(jù)傳輸中的應(yīng)用實(shí)例

    們轉(zhuǎn)換成文本格式。 Base64編碼原理 Base64編碼是一種二進(jìn)制到文本的編碼方法,它將每3個(gè)字節(jié)的二進(jìn)制數(shù)據(jù)編碼為4個(gè)ASCII字符。這種編碼方式確保了編碼后的數(shù)據(jù)只包含ASCII字符集中的字符,從而可以安全地在各種文本格
    的頭像 發(fā)表于 11-10 10:50 ?501次閱讀

    base64編碼和解碼的使用方法

    Base64編碼是一種廣泛使用的編碼方案,用于將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為純文本格式。這種編碼方式特別適用于在不支持二進(jìn)制數(shù)據(jù)的系統(tǒng)之間傳輸數(shù)據(jù),例如電子郵件、網(wǎng)頁等。 1. Base64編碼簡介
    的頭像 發(fā)表于 11-10 10:48 ?1165次閱讀

    鴻蒙語言基礎(chǔ)類庫:ohos.util util工具函數(shù)

    該模塊主要提供常用的工具函數(shù),實(shí)現(xiàn)字符串編解碼(TextEncoder,TextDecoder)、有理數(shù)運(yùn)算(RationalNumber)、緩沖區(qū)管理(LruBuffer)、范圍判斷(Scope)、Base64編解碼(Base64
    的頭像 發(fā)表于 07-09 16:56 ?558次閱讀
    鴻蒙<b class='flag-5'>語言</b>基礎(chǔ)類庫:ohos.util util工具函數(shù)

    請(qǐng)問esp32如何將16進(jìn)制字符串轉(zhuǎn)換成base64格式?

    請(qǐng)問 esp32 如何將 16進(jìn)制字符串轉(zhuǎn)換成base64格式
    發(fā)表于 06-24 08:35

    labview把圖片轉(zhuǎn)成base64

    各位大佬們,請(qǐng)教一下如何在labview中把圖片轉(zhuǎn)成base64編碼,然后傳給Python,或者是然后用labview和Python之間傳遞圖片,求大神指教該怎么寫
    發(fā)表于 05-08 01:04

    什么是Base64,如何編解碼?

    Base64編碼的原理是將輸入數(shù)據(jù)分割成固定長度的塊(通常是3個(gè)字節(jié)),然后將每個(gè)塊轉(zhuǎn)換為4個(gè)Base64字符。這四個(gè)字符由64個(gè)特定的ASCII字符組成,包括大寫字母A-Z、小寫字母a-z、數(shù)字0-9以及兩個(gè)額外的字符+/。編
    發(fā)表于 05-03 17:36 ?744次閱讀

    鴻蒙OS開發(fā)問題:(ArkTS) 【解決中文亂碼 string2Uint8Array、uint8Array2String】

    在進(jìn)行base64編碼中,遇到中文如果不進(jìn)行處理一定會(huì)出現(xiàn)亂碼
    的頭像 發(fā)表于 03-27 21:38 ?2285次閱讀
    鴻蒙OS開發(fā)問題:(ArkTS) 【解決中文亂碼 string2Uint8Array、uint8Array2String】