C# base64URL编码

C#中有对应的Base64处理函数:例如把byte[] 转成base64字符串Convert.ToBase64String

base64是用64个字符来表示任意二进制数据的方法,它对二进制数据进行处理,它把每6bit前缀补0转成8bit后,再查base64字符表得到转化后的结果。

base64编码所用的64个字符为:A-Za-z0-9+/

base64URL编码基于base64编码,把字符+和/分别变成-和_。

同理:还有base58, base58去掉了0(数字0)、O (大写字母O)、 I (大写的字母i) and l (小写的字母L) 、/、 +等。

在java8中有对应的处理函数:Base64.getUrlEncoder().encodeToString

C#中没有找到对应的处理函数,基于以上理解可以直接做字符替换:

    string temp = Convert.ToBase64String(dataBytes);
    string basedTimeStr = temp.Replace("+", "-").Replace("/", "_");

应用实例:unix时间戳的编码成6位字符串的算法:

java代码为:

public class Base64URLEncoder {
 
       public static String encode(long ts) {
             return Base64.getUrlEncoder().encodeToString(ByteBuffer.allocate(Long.BYTES).putLong((ts / 1000) << 28).array())
                          .substring(0, 6);
       }

C#代码为:

 /// <summary>
        /// 时间编码
        /// </summary>
        /// <param name="dtNow">当前本地时间</param>
        /// <returns></returns>
        string GetDate(DateTime dtNow)
        {
            DateTime dtStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            TimeSpan span = dtNow.ToUniversalTime() - dtStart;
            long currentTimeSeconds= (long)(span.TotalSeconds) << 28;
            var dataBytes = BitConverter.GetBytes(currentTimeSeconds);
            Array.Reverse(dataBytes);
            string temp = Convert.ToBase64String(dataBytes);
            string basedTimeStr = temp.Replace("+", "-").Replace("/", "_"); ;
            string result = basedTimeStr.Substring(0, 6);//只返回前6位
            return result;
        }

        /// <summary>
        /// 时间解码
        /// </summary>
        /// <param name="code"></param>
        /// <returns>返回本地时间</returns>
        DateTime DeCodeDate(string code)
        {
            byte[] bytes = Convert.FromBase64String(code);
            Array.Reverse(bytes);
            ulong tt = BitConverter.ToUInt64(bytes, 0);
            DateTime dtStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            //DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0));
            long unixTime = (long)tt >> 28;
            return dtStart.AddSeconds(unixTime).ToLocalTime();
        }

对应的另外一种算法2,对64取模:

        string s_base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
        string GetDate2(DateTime dtNow)
        {
            DateTime dtStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            TimeSpan span = dtNow.ToUniversalTime() - dtStart;
            long sek =(long) Math.Floor(span.TotalSeconds);
            StringBuilder stringBuilder = new StringBuilder();
            while (sek > 0)
            {
                long n = sek % 64;
                char baseStr = s_base64url[(int)n];
                stringBuilder.Insert(0,baseStr);
                sek = (long)Math.Floor((double)sek/64);
            }
            return stringBuilder.ToString().PadLeft(6,'A');
        }

 算法2的计算过程同base58的方式,之所以计算1和计算2结果相同,是因为本质都是64进制。

对算法1中左移28位(<<28)的理解:

因为base64是每6bit一个转码,如果需求是把时间戳转成6位字符,则时间戳从低位开始的6*6=36有效,剩下64-36=28位都是0,其他位都是1,则最大可表示的年月日为:4147/8/20 15:32:15

  string longBinaryStr = "00000000 00000000 00000000 00001111 11111111 11111111 11111111 11111111".Replace(" ","");
            long unixTime = Convert.ToInt64(longBinaryStr, 2);
            DateTime dt = dtStart.AddSeconds(unixTime).ToLocalTime();

 <<28

基于上面的理解:写一个解码函数:

 private void DecodeBase64URLString(string code)
        {    
            string s_base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";        
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 6; i++)
            {
                byte ch_index = (byte)s_base64url.IndexOf(code[i]);
                string tempBinary = Convert.ToString(ch_index, 2).PadLeft(6,'0');
                sb.Append(tempBinary);
            }
            for (int i = sb.Length; i < 64; i++)
            {
                sb.Append("0");
            }
            long unix = Convert.ToInt64(sb.ToString(), 2);
            DateTime dtStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            long test = (long)unix >> 28;
            DateTime dtR= dtStart.AddSeconds(test).ToLocalTime();
            this.txtDate.Text = dtR.ToString("yyyy-MM-dd HH:mm:ss");
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 在HTML5中,可以使用base64编码来将图片转换为字符串形式,以便在网页中显示。通过将图片转换为base64编码的字符串,可以直接将其嵌入到HTML代码中,而不需要额外的图片文件。这样可以减少网页的加载时间和请求次数。同时,也可以使用base64编码的字符串作为数据传输的方式,例如通过Ajax请求将图片数据传输到服务器。\[1\]在PHP中,可以使用base64_encode()函数将图片文件编码base64字符串。例如,可以使用以下代码将名为"wg.png"的图片文件编码base64字符串并输出到浏览器上: echo base64_encode(file_get_contents('wg.png'));\[1\]在C#中,可以使用Base64ToImage()函数将base64字符串转换为图片对象,或使用ImageToBase64()函数将图片对象转换为base64字符串。这些函数可以用于将base64编码的图片数据转换为可用于显示或存储的图片对象,或将图片对象转换为base64编码的字符串。\[2\]需要注意的是,标准的Base64编码并不适合直接放在URL中传输,因为URL编码器会将Base64中的"/"和"+"字符转换为形如"%XX"的形式。在存入数据库时,还需要进行进一步的转换,因为ANSI SQL中已将"%"号用作通配符。\[3\] #### 引用[.reference_title] - *1* *3* [html image -- data:image/png;base64](https://blog.csdn.net/weixin_36122809/article/details/118168033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C# Image转化成base64](https://blog.csdn.net/qq_37944029/article/details/108102300)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值