最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#之關(guān)于Base64簡單加密與解密方式

 更新時間:2023年06月16日 16:56:49   作者:斯內(nèi)科  
這篇文章主要介紹了C#之關(guān)于Base64簡單加密與解密方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Base64屬于簡單加密算法的一種

類似于凱撒密碼【它是一種替換加密的技術(shù)

Base64字符串由65個字符組成

  • 大寫字母A~Z,
  • 小寫字母a~z,
  • 數(shù)字0~9,以及三個特殊字符+、/、=  
  • 【=“等號”用于補充字符,使Base64字符串長度變成4的倍數(shù)】

規(guī)則

考慮到初始源字符串可能是任何文本編碼的【中文GBK,Unicode,ASCII等】,因此Base64字符串加密只處理字節(jié)數(shù)組【字節(jié)數(shù)組通過encoding.GetBytes(string src)獲得】。

Base64編碼字符串的長度一定是4的倍數(shù)。

Base64要求把每三個8Bit的字節(jié)轉(zhuǎn)換為四個6Bit的字節(jié)(3*8 = 4*6 = 24),然后把6Bit再添兩位高位0,組成四個8Bit的字節(jié),因此每個Base64字節(jié)的十進制范圍為0~63。也就是說,轉(zhuǎn)換后的字符串理論上將要比原來的長1/3。

字節(jié)數(shù)組的長度應(yīng)該是3的倍數(shù),如果這個條件不能滿足的話,

具體的解決辦法是這樣的:

原文剩余的字節(jié)根據(jù)編碼規(guī)則繼續(xù)單獨轉(zhuǎn)(1變2,2變3;不夠的位數(shù)用0補全),再用=號補滿4個字節(jié)。

這就是為什么有些Base64編碼會以一個或兩個等號結(jié)束的原因,但等號最多只有兩個。

因為一個原字節(jié)至少會變成兩個目標(biāo)字節(jié),所以余數(shù)任何情況下都只可能是0,1,2這三個數(shù)中的一個。

如果余數(shù)是0的話,就表示原文字節(jié)數(shù)正好是3的倍數(shù)(最理想的情況)。

如果是1的話,轉(zhuǎn)成2個Base64編碼字符,為了讓Base64編碼是4的倍數(shù),就要補2個等號;同理,如果是2的話,就要補1個等號。 

6Bit數(shù)字【0~63】映射Base64字符表如下

索引

對應(yīng)字符

索引

對應(yīng)字符

索引

對應(yīng)字符

索引

對應(yīng)字符

0

A

17

R

34

i

51

z

1

B

18

S

35

j

52

0

2

C

19

T

36

k

53

1

3

D

20

U

37

l

54

2

4

E

21

V

38

m

55

3

5

F

22

W

39

n

56

4

6

G

23

X

40

o

57

5

7

H

24

Y

41

p

58

6

8

I

25

Z

42

q

59

7

9

J

26

a

43

r

60

8

10

K

27

b

44

s

61

9

11

L

28

c

45

t

62

+

12

M

29

d

46

u

63

/

13

N

30

e

47

v

14

O

31

f

48

w

15

P

32

g

49

x

16

Q

33

h

50

y

測試Base64源程序

新建WinForm應(yīng)用程序Base64EncoderDemo,重命名默認(rèn)的 Form1為FormBase64Encoder,

窗體FormBase64Encoder設(shè)計如圖:

FormBase64Encoder.cs主要代碼如下

(忽略設(shè)計器自動生成的代碼):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Base64EncoderDemo
{
    public partial class FormBase64Encoder : Form
    {
        public FormBase64Encoder()
        {
            InitializeComponent();
            //參考Convert微軟源程序
            //https://referencesource.microsoft.com/#mscorlib/system/convert.cs,fc990bd1275d43d6
        }
        private void FormBase64Encoder_Load(object sender, EventArgs e)
        {
            rtxtMessage.ReadOnly = true;
            //編碼格式
            cboEncoding.Items.AddRange(new string[] { "ASCII", "Unicode", "UTF-8", "GBK" });
            cboEncoding.SelectedIndex = 0;
        }
        private void btnClear_Click(object sender, EventArgs e)
        {
            rtxtSourceString.Clear();
            rtxtBase64String.Clear();
            rtxtMessage.Clear();
        }
        /// <summary>
        /// 顯示提示消息
        /// </summary>
        /// <param name="content"></param>
        private void DisplayMessage(string content)
        {
            if (rtxtMessage.TextLength >= 20480)
            {
                rtxtMessage.Clear();
            }
            rtxtMessage.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} -> {content}\n");
            rtxtMessage.ScrollToCaret();
        }
        private void btnConvertBase64_Click(object sender, EventArgs e)
        {
            rtxtBase64String.Clear();
            if (rtxtSourceString.Text.Trim().Length == 0)
            {
                rtxtSourceString.Focus();
                DisplayMessage("源字符串不能為空");
                return;
            }
            try
            {
                Encoding encoding = Encoding.GetEncoding(cboEncoding.Text);
                byte[] buffer = encoding.GetBytes(rtxtSourceString.Text.Trim());
                rtxtBase64String.Text = Convert.ToBase64String(buffer, Base64FormattingOptions.None);
                DisplayMessage($"轉(zhuǎn)換成功,Base64字符串【{rtxtBase64String.Text}】");
            }
            catch (Exception ex)
            {
                DisplayMessage($"轉(zhuǎn)換為Base64時出錯:【{ex.Message}】");
            }
        }
        private void btnRestore_Click(object sender, EventArgs e)
        {
            rtxtSourceString.Clear();
            if (rtxtBase64String.Text.Trim().Length == 0)
            {
                rtxtBase64String.Focus();
                DisplayMessage("Base64字符串不能為空");
                return;
            }
            try
            {
                Encoding encoding = Encoding.GetEncoding(cboEncoding.Text);
                byte[] buffer = Convert.FromBase64String(rtxtBase64String.Text);
                rtxtSourceString.Text = encoding.GetString(buffer);
                DisplayMessage($"還原成功,源字符串【{rtxtSourceString.Text}】");
            }
            catch (Exception ex)
            {
                DisplayMessage($"還原字符串時出錯:【{ex.Message}】");
            }
        }
    }
}

程序運行如圖

參考微軟源代碼

Reference Source

public static unsafe String ToBase64String(byte[] inArray, int offset, int length, Base64FormattingOptions options) {
            //Do data verfication
            if (inArray==null) 
                throw new ArgumentNullException("inArray");
            if (length<0)
                throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
            if (offset<0)
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
            if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
                throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
            Contract.Ensures(Contract.Result<string>() != null);
            Contract.EndContractBlock();
            int inArrayLength;
            int stringLength;
            inArrayLength = inArray.Length;
            if (offset > (inArrayLength - length))
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
            if (inArrayLength == 0)
                return String.Empty;
            bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
            //Create the new string.  This is the maximally required length.
            stringLength = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
            string returnString = string.FastAllocateString(stringLength);
            fixed (char* outChars = returnString){
                fixed (byte* inData = inArray) {
                    int j = ConvertToBase64Array(outChars,inData,offset,length, insertLineBreaks);
                    BCLDebug.Assert(returnString.Length == j, "returnString.Length == j");
                    return returnString;
                }
            }
        }

Base64處理字節(jié)數(shù)組邏輯函數(shù)

internal static readonly char[] base64Table = {'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','+','/','=' };        
        private const Int32 base64LineBreakPosition = 76;     
[System.Security.SecurityCritical]  // auto-generated
        private static unsafe int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length, bool insertLineBreaks) {
            int lengthmod3 = length%3;
            int calcLength = offset + (length - lengthmod3);
            int j=0;
            int charcount = 0;
            //Convert three bytes at a time to base64 notation.  This will consume 4 chars.
            int i;
            // get a pointer to the base64Table to avoid unnecessary range checking
            fixed(char* base64 = base64Table) {
                for (i=offset; i<calcLength; i+=3)
                {
                    if (insertLineBreaks) {
                        if (charcount == base64LineBreakPosition) {
                            outChars[j++] = '\r';
                            outChars[j++] = '\n';
                            charcount = 0;
                        }
                        charcount += 4;
                    }
                    outChars[j] = base64[(inData[i]&0xfc)>>2];
                    outChars[j+1] = base64[((inData[i]&0x03)<<4) | ((inData[i+1]&0xf0)>>4)];
                    outChars[j+2] = base64[((inData[i+1]&0x0f)<<2) | ((inData[i+2]&0xc0)>>6)];
                    outChars[j+3] = base64[(inData[i+2]&0x3f)];
                    j += 4;
                }
                //Where we left off before
                i =  calcLength;
                if (insertLineBreaks && (lengthmod3 !=0) && (charcount == base64LineBreakPosition)) {
                    outChars[j++] = '\r';
                    outChars[j++] = '\n';
                }
                switch(lengthmod3)
                {
                case 2: //One character padding needed
                    outChars[j] = base64[(inData[i]&0xfc)>>2];
                    outChars[j+1] = base64[((inData[i]&0x03)<<4)|((inData[i+1]&0xf0)>>4)];
                    outChars[j+2] = base64[(inData[i+1]&0x0f)<<2];
                    outChars[j+3] = base64[64]; //Pad
                    j+=4;
                    break;
                case 1: // Two character padding needed
                    outChars[j] = base64[(inData[i]&0xfc)>>2];
                    outChars[j+1] = base64[(inData[i]&0x03)<<4];
                    outChars[j+2] = base64[64]; //Pad
                    outChars[j+3] = base64[64]; //Pad
                    j+=4;
                    break;
                }
            }
            return j;
        }
        private static int ToBase64_CalculateAndValidateOutputLength(int inputLength, bool insertLineBreaks) {
            long outlen = ((long)inputLength) / 3 * 4;          // the base length - we want integer division here. 
            outlen += ((inputLength % 3) != 0) ? 4 : 0;         // at most 4 more chars for the remainder
            if (outlen == 0)
                return 0;
            if (insertLineBreaks) {
                long newLines = outlen / base64LineBreakPosition;
                if ((outlen % base64LineBreakPosition) == 0) {
                    --newLines;    
                }
                outlen += newLines * 2;              // the number of line break chars we'll add, "\r\n"
            }
            // If we overflow an int then we cannot allocate enough
            // memory to output the value so throw
            if (outlen > int.MaxValue)
                throw new OutOfMemoryException();
            return (int)outlen;
        }

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • c#之滾動字幕動畫窗體的實現(xiàn)詳解

    c#之滾動字幕動畫窗體的實現(xiàn)詳解

    本篇文章是對c#中滾動字幕動畫窗體的實現(xiàn)方法進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • WinForm實現(xiàn)的圖片拖拽與縮放功能示例

    WinForm實現(xiàn)的圖片拖拽與縮放功能示例

    這篇文章主要介紹了WinForm實現(xiàn)的圖片拖拽與縮放功能,結(jié)合具體實例形式分析了WinForm鼠標(biāo)事件響應(yīng)及圖片元素動態(tài)操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-05-05
  • C# Partial:分部方法和分部類代碼實例

    C# Partial:分部方法和分部類代碼實例

    這篇文章主要介紹了C# Partial:分部方法和分部類代碼實例,本文直接給出代碼實現(xiàn),需要的朋友可以參考下
    2015-03-03
  • C# WPF實現(xiàn)頁面跳轉(zhuǎn)的兩種方法介紹

    C# WPF實現(xiàn)頁面跳轉(zhuǎn)的兩種方法介紹

    在 C# WPF 中,頁面跳轉(zhuǎn)通常有兩種主要方式:使用 NavigationWindow+Page或在 Window 中切換 UserControl,下面我們來看看具體實現(xiàn)方法吧
    2025-10-10
  • 一篇文章徹底搞清楚c#中的委托與事件

    一篇文章徹底搞清楚c#中的委托與事件

    這篇文章主要給大家介紹了如何通過一篇文章徹底搞清楚c#中的委托與事件,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用c#具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 使用C#和ZXing開發(fā)的碼生成與識別軟件

    使用C#和ZXing開發(fā)的碼生成與識別軟件

    在當(dāng)今數(shù)字化時代,二維碼、條形碼等各種碼的應(yīng)用無處不在,今天咱就來聊聊怎么用C#語言搭配ZXing庫開發(fā)一款碼生成與識別的軟件,這過程可有趣啦,需要的朋友可以參考下
    2025-12-12
  • c# 圓形識別方案和直線識別方案的參考示例

    c# 圓形識別方案和直線識別方案的參考示例

    這篇文章主要介紹了c# 圓形識別方案和直線識別方案的實現(xiàn)示例,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03
  • 詳解C#如何利用爬蟲技術(shù)實現(xiàn)快捷租房

    詳解C#如何利用爬蟲技術(shù)實現(xiàn)快捷租房

    做為一個碼農(nóng),大部分都集中在一二線城市,所以租房也就無可避免,面對如今五花八門的租房信息,往往很難找到合適的房子。本文教你如何利用爬蟲技術(shù)實現(xiàn)快捷租房,感興趣的可以了解一下
    2022-09-09
  • windows系統(tǒng)下,如何在C#程序中自動安裝字體

    windows系統(tǒng)下,如何在C#程序中自動安裝字體

    在Windows系統(tǒng)中,原有自帶的字體樣式有限,有時候我們的程序會使用到個別稀有或系統(tǒng)不自帶的字體。因此我們需要將字體打包到程序中,當(dāng)程序啟動時,檢測系統(tǒng)是否有該字體,如果沒有則安裝該字體,也可以動態(tài)加載字體。
    2020-11-11
  • 使用淘寶ip地址庫查ip的示例

    使用淘寶ip地址庫查ip的示例

    這篇文章主要介紹了使用淘寶ip地址庫查ip的示例,需要的朋友可以參考下
    2014-03-03

最新評論

保山市| 无锡市| 罗江县| 札达县| 普宁市| 武安市| 阿鲁科尔沁旗| 县级市| 洛浦县| 三亚市| 嘉义市| 玛曲县| 蒲江县| 绍兴市| 大田县| 兰坪| 张家界市| 文登市| 内江市| 大同市| 六安市| 建昌县| 图片| 邛崃市| 麻城市| 涟水县| 沙田区| 万安县| 家居| 怀化市| 紫金县| 天台县| 吉水县| 垣曲县| 定陶县| 江华| 宁海县| 怀远县| 清涧县| 卢龙县| 涟水县|