需要使用 Base64 格式吗?那么本网站正好适合您!使用我们的在线工具对数据进行编码或解码,便捷好用。

Visual Basic 中的 Base64 编码:完整指南

这是一个 Visual Basic 开发者遇了二十五年的问题:你手上有张 JPEG、一团二进制、一个许可证文件,或一句再普通不过的话,而你面前的通道只收文本。一个 JSON 字段、一个环境变量、一个邮件附件、一条 URL、一个配置文件、一个按文本类型声明的数据库列,加上大楼里所有的其他门,共享同一条规则:只要可打印字符。Base64 就是那个放行二进制的门卫。它把你的字节改写成字母、数字、加号、斜杠和等号组成的流,于是任何以文本形式旅行的东西都能捎上它们。好消息是:你将来可能用得上的每一个编码器部件,都已经在 .NET 运行时里了。没有包,没有组件,没有仪式。

一口气说完,因为本站首页已经把格式本身讲得很深:Base64 拿三个输入字节,把它们写成 64 符号字母表中的四个字符,当字节数除不平时,末尾加一个或两个 = 字符。四换三的交换正是编码数据比原文大约大三分之一的原因,这就是那个著名的尺寸税,每编码一次交一次。本文其余的一切,都关于让你产出的编码恰好满足下一个系统的期待:正确的字母表、正确的填充、正确的换行,和正确的字符集。

编码器工具箱:一切都内置

运行时的编码一侧和解码一侧一样,经历了同样的四波生长,所以工具箱有一条长长的、仍然受支持的选项尾巴。这是完整的家族,以及每一个各自为何种工作而生:

API 可用版本 适用场景
System.Convert.ToBase64String .NET Framework 1.1(2003) 经典款。进一块数组,出一根字符串,带数组子集、span 和可选 MIME 风格换行的重载。
System.Convert.ToBase64CharArray .NET Framework 1.1(2003) 把编码字符写进你已分配的字符缓冲区,并返回用掉了多少字符。
System.Convert.TryToBase64Chars .NET Core 2.1(2018) 基于 span、分配轻省的编码,写进你提供的字符 span,用布尔值作答而不是抛异常。
System.Buffers.Text.Base64 .NET Core 2.1(2018) 底层、基于 span 的编码:写进你自己的 UTF-8 缓冲区、原地膨胀,再用 GetMaxEncodedToUtf8Length 给缓冲区定尺寸。
System.Buffers.Text.Base64Url .NET 9(2024) URL 安全字母表(用 -_ 代替 +/),不带填充。在更老的运行时上,它搭载在 Microsoft.Bcl.Memory NuGet 包里。
ToBase64Transform + CryptoStream .NET Framework 1.1(2003) 流式编码:分块读文件,写出编码文本,巨量输入下内存保持平坦。

看看版本版图:.NET 10 是当前长期支持版本(2025 年 11 月发布,支持到 2028 年 11 月),.NET 8 和 .NET 9 支持到 2026 年 11 月,.NET 11 正处于预览,还有一批新的 Base64 便捷方法在路上。上表的一切在所有这些版本上都稳定。唯一的版本门槛是 Base64Url:从 .NET 9 起内置,在 .NET Framework 4.6.2 及以上通过 Microsoft.Bcl.Memory 包可用,而这也是本文唯一会要求你安装的包。要搞一个临时项目,.NET SDK 盒子里就带着 Visual Basic:

dotnet new console -lang VB -o Packer
cd Packer
dotnet run

你的第一次编码:字节进,文本出

Visual Basic 编码生涯的百分之九十是两个调用,而且顺序要紧:编码器吃的是字节,不是文本,所以如果你从字符串出发,得先选一个编码把它变成字节,然后才轮到 Base64 那一步。这是完整的舞蹈:

Imports System
Imports System.Text
Module Encoder
    Sub Main()
        Dim text As String = "Man"
        Dim bytes() As Byte = Encoding.UTF8.GetBytes(text)
        Dim packed As String = System.Convert.ToBase64String(bytes)
        Console.WriteLine(packed)
        ' TWFu
    End Sub
End Module

中间那三行就是这门手艺的全部,而字符串 "TWFu" 是你写的任何编码器的完美冒烟测试。重载在你需要时给你控制力。子集形式编码数组的一段,而无需先把它拷贝出来,当真正的负载蹲在一块更大的缓冲区里时,这很方便:

Imports System
Module SlicePacker
    Sub Main()
        Dim data() As Byte = {1, 2, 3, 4, 5, 6, 7, 8}
        Dim packed As String = System.Convert.ToBase64String(data, 2, 4)
        Console.WriteLine(packed)
        ' AwQFBg==  (只编码了第 3 到 6 个字节)
    End Sub
End Module

还有数组转字符形式,ToBase64CharArray,写进你分配的字符缓冲区并告诉你填了多少字符,当目的地是你手工搭建的某个更大文本结构的一部分时,它是趁手的工具。注意 Visual Basic 语法的家规:字节数组要写成带空括号的 Byte()。丢掉括号你就只有一个字节,而 Option Strict On(模板里默认是关的 - 值得在每个项目里打开)会在编译期抓住这个混淆。

塑造输出:填充、换行与精确尺寸

把同样的字节编码两次,完全可以合法地产生两根不同的字符串,而差异全都归结为输出塑造。第一,填充:当输入长度不是 3 的倍数时,编码器用一到两个 = 字符给最后一组补齐。RFC 说除非你遵循的规范另有说明,否则要带上它们,而 ToBase64String 默认就带上。第二,换行:格式化重载的第二个参数 Base64FormattingOptions.InsertLineBreaks,让编码器发出以 CRLF 分隔的 76 字符行,这正是 MIME 规则。MIME 本身就用 76 字符限制,这是老 PEM 64 字符行的近亲,而这两个限制都追溯到 SMTP 内部的限制。如果你的消费者是邮件管道,就打开换行;如果它是一条 URL、一个 JSON 字段或一个数据库列,就关掉,因为藏在数据里的隐形 CRLF 总会找到办法在后面吓你一跳:

Imports System
Module MimePacker
    Sub Main()
        Dim data(113) As Byte
        For i As Integer = 0 To 113
            data(i) = CByte(i)
        Next
        Dim wrapped As String = System.Convert.ToBase64String(data, Base64FormattingOptions.InsertLineBreaks)
        Console.WriteLine(wrapped.Length)
        ' 154:两行 76 字符,中间夹一个 CRLF
    End Sub
End Module

第三,精确尺寸,因为你会想预先分配缓冲区和列宽。规则是每三个输入字节四个字符,向上取整:1000 字节变成 1336 个字符。与其手工做算术,不如用运行时里的辅助方法,它返回给定输入大小的最大编码长度,这正是你传给缓冲区分配的数字:

Imports System.Buffers.Text
Module Sizing
    Sub Main()
        Dim dataLength As Integer = 1000
        Dim textNeeded As Integer = Base64.GetMaxEncodedToUtf8Length(dataLength)
        Console.WriteLine(textNeeded)
        ' 1336
    End Sub
End Module

同一个四换三的比例就是尺寸税最纯粹的样子:每个编码值都比它携带的字节大约大 33%,所以规划你的存储和传输尺寸时要带着这个余量。还有一个行为值得在咬到你之前知道:如果你解码一根字符串再重新编码结果,新字符串不保证和原来的一致,因为空白消失了、填充被规范化了。需要比较值时,比较解码后的字节,而不是编码文本。

编码前选择字符集

因为文本编码的第一步是"字符串到字节",你挑的字符集决定了接收方解码时看到什么。Visual Basic 字符串在运行时内部是 UTF-16,但你发出的字节应该匹配对方期待读到的东西,而选择菜单很短:

  • Encoding.UTF8:web、API 和任何现代场景的正确默认值。它能往返这门语言能持有的每一个 Unicode 字符。
  • Encoding.Unicode:UTF-16 小端。当管道两端都是明确约定了 UTF-16 的 .NET 程序时是个合理选择,仅此而已。
  • Encoding.ASCII:只有 7 位,其他任何东西都会被悄悄替换成问号。把 "Café" 编码成 ASCII,你得到的是 "Caf?" 的字节,解码回去就是那个样子,问号一个不少。
  • Encoding.Default:在 .NET Framework 上它是机器的 ANSI 代码页,但在 .NET(Core)上它永远是 UTF-8,与区域设置无关。对你交换的数据仍然要避开它 - 显式说出编码,通常是 UTF-8。
Imports System
Imports System.Text
Module CharsetPacker
    Sub Main()
        Dim text As String = "Café"
        Dim utf8() As Byte = Encoding.UTF8.GetBytes(text)
        Dim ascii() As Byte = Encoding.ASCII.GetBytes(text)
        Console.WriteLine(System.Convert.ToBase64String(utf8))
        ' Q2Fmw6k=
        Console.WriteLine(System.Convert.ToBase64String(ascii))
        ' Q2FmPw==  (重音符号变成了问号)
    End Sub
End Module

两根不同的 Base64 字符串,同一个单词,只有一根能活过旅途。实用规则:除非你遵循的协议点了另一套方案的名,就把文本编码为 UTF-8 并说明白。

Base64Url:能在 URL 里活下来的字母表

标准字母表包含 +/,而这两个字符在 URL 内部都有各自的职责,所以建立在那套字母表上的 Base64 一旦落进查询字符串或路径段就会坏掉。解决办法已在 RFC 4648 第 5 节标准化:把两个闯祸鬼换成 URL 安全的 -_,并且通常丢掉末尾填充,因为数据长度已经告诉了解码器数据在哪里结束。这个变体被称为 base64url,是 JWT、API 令牌和越来越多 API 的字母表。.NET 9 为它添加了一个专用类,它带着一个值得知道的立场被构建出来:按设计省略填充:

Imports System.Buffers.Text
Module UrlSafePacker
    Sub Main()
        Dim data() As Byte = {219, 255, 0, 63, 16}
        Dim packed As String = Base64Url.EncodeToString(data)
        Console.WriteLine(packed)
        ' 2_8APxA  (下划线,末尾无填充)
    End Sub
End Module

上面的例子选得好:挑的字节让其中一个特殊字符现身 - 下划线,标准字母表在那个位置是斜杠 - 于是你能亲眼看到替换发生。当你在更老的运行时上,同样的字母表就是两次字符替换加一次修剪,你得到一个可直接替换的结果:

Imports System
Module CompatPacker
    Function ToUrlSafe(ByVal packed As String) As String
        Return packed.Replace("+"c, "-"c).Replace("/"c, "_"c).TrimEnd("="c)
    End Function
End Module

在 .NET Framework 4.6.2 或更新的版本上,Microsoft.Bcl.Memory 包可以直接给你真正的 Base64Url 类。无论如何,留意填充这条划在沙地上的线:.NET 的 Base64Url 输出没有填充,而其他生态里的一些库会加上(还有一些严格的解码器坚持要求它)。比如 JWT 要求不带填充的形式,所以 .NET 的默认值在那里恰好正确。当你跨越生态边界时,在发出字符串之前先确认另一侧的期待。

打包文件

文件是原始用例:把一个二进制文件变成一个文本文件,让邮件、FTP 和配置系统都乐意携带。在 Visual Basic 里,整个活就是三个调用,其中一个读,一个写:

Imports System.IO
Module FilePacker
    Sub Main()
        Dim bytes() As Byte = File.ReadAllBytes("photo.png")
        Dim packed As String = System.Convert.ToBase64String(bytes)
        File.WriteAllText("photo.b64", packed)
    End Sub
End Module

把尺寸比例装进口袋:一张 10 兆字节的照片变成一个大约 13.4 兆字节的文本文件。这个操作在现代硬件上很快(下文细说),所以成本几乎总是存储和带宽而不是 CPU,这是 33% 税的常规账单。当文件只是待在引用它的文本旁边时,这个模式完全没问题;当文件又大又长寿时,问一问通道是否真的需要文本形态。

图片:手工搭建 Data URI

data URI 方案(RFC 2397)把文件内容直接嵌进 URL:data:、媒体类型、字面标记 ;base64、一个逗号,和编码字节。浏览器用它们内联小图片和字体。WPF 不能直接消费 data URI - BitmapImage 没有处理 data: 方案的处理器 - 所以惯用的动作是剥掉前缀,把字节递给一个 MemoryStream。在 Visual Basic 里搭建 URI 是一次字符串拼接,消费它是一小块初始化代码:

Imports System.IO
Imports System.Windows.Media.Imaging
Module DataUriPacker
    Sub Main()
        Dim bytes() As Byte = File.ReadAllBytes("logo.png")
        Dim dataUri As String = "data:image/png;base64," & System.Convert.ToBase64String(bytes)
        Dim image As New BitmapImage()
        image.BeginInit()
        image.StreamSource = New MemoryStream(System.Convert.FromBase64String(dataUri.Substring(dataUri.IndexOf(","c) + 1)))
        image.EndInit()
        ' 现在可以把 image 赋给一个 Image 控件了
    End Sub
End Module

RFC 本身警告 data URI 只对短值有用,HTML 文档又各自施加属性长度限制,所以明智的范围是图标、头像、缩略图和小小的背景图案。媒体类型必须匹配你实际编码的字节,因为下游没有任何东西会从内容重新推导出它。

HTTP:认证头部与 JSON 负载

在线路上,你会手工编码的两个地方是 HTTP Basic 认证头部,以及携带二进制或预编码数据的 JSON 字段。Basic 认证最显眼:头部是单词 Basic、一个空格,和用冒号连接后的 username:password 的 Base64。搭它就是一个编码调用:

Imports System
Imports System.Text
Module AuthPacker
    Function MakeBasicHeader(ByVal user As String, ByVal password As String) As String
        Dim raw() As Byte = Encoding.UTF8.GetBytes(user & ":" & password)
        Return "Basic " & System.Convert.ToBase64String(raw)
    End Function
End Module

JSON 的情况同样例行。如果 API 想在请求体里要一张图片或一个证书,你把字节编码好,把字符串丢进负载,System.Text.Json(从 .NET Core 3.0 起就在盒子里)处理周围的序列化:

Imports System.Text.Json
Module ApiPacker
    Function WidgetPayload(ByVal name As String, ByVal imageBytes() As Byte) As String
        Dim payload = New With {
            .name = name,
            .image = System.Convert.ToBase64String(imageBytes)
        }
        Return JsonSerializer.Serialize(payload)
    End Function
End Module

两条家规:凭据只走 HTTPS,因为在纯 HTTP 上 Base64 是戏服,不是锁;永远别把原始认证头部或它解码出的凭据写进日志。

邮件附件与 MIME 折行

邮件是 Base64 谋生的地方。SMTP 是为 7 位 ASCII 建造的,所以二进制附件必须先变成文本才能起飞,MIME 标准(RFC 2045)做了选择:Base64,每行折在 76 字符,用 Content-Transfer-Encoding: base64 头部声明。如果你打交道的 System.Net.Mail 类,整个仪式就是两行搭建,因为邮件库会在发送时替你完成折行:

Imports System.IO
Imports System.Net.Mail
Imports System.Net.Mime
Module MailPacker
    Sub Main()
        Using message As New MailMessage("me@example.com", "you@example.com")
            message.Subject = "Quarterly report"
            message.Body = "Please find the report attached."
            Using stream As New FileStream("report.bin", FileMode.Open, FileAccess.Read)
                Dim attachment As New Attachment(stream, "report.bin")
                attachment.TransferEncoding = TransferEncoding.Base64
                message.Attachments.Add(attachment)
            End Using
        End Using
    End Sub
End Module

只有在你手工写原始 MIME 文本时,才需要自己用 Base64FormattingOptions.InsertLineBreaks 产出折行形式:邮件测试夹具、遗留网关,或一个吐 .eml 文件的工具。76 字符规则不是风格偏好;一些接收系统会截断更长的行,这就是为什么这个限制在标准里存活了几十年。

存储编码值:数据库、配置文件与环境变量

只存文本的存储场所总是在向 Base64 招手:一个按文本类型声明的数据库列、一个 XML 配置值、一个环境变量。你编码字节,存下字符串,出去时再解码。编码侧永远是同一行式,但存储侧有限制,让尺寸税变得具体。SQL Server 里一个普通的 VARCHAR 列停在 8,000 字符(NVARCHAR 列停在它的一半,4,000 字符,因为每个 Unicode 字符花两个字节)- 8,000 字符大约容得下 6,000 字节的二进制,33% 的开销还没把你推过界,再往上就得找 MAX 类型,或者更诚实地说,找一个真正的二进制列。在 Windows 上,单个用户自定义环境变量上限是 32,767 字符(在 XP 时代的系统上,整个环境块也被卡在那个尺寸上),所以"把整个许可证数据留在一个环境变量里"是有硬上限的:

Imports System
Module EnvPacker
    Sub Main()
        Dim blob() As Byte = {1, 2, 3, 4, 5}
        Dim packed As String = System.Convert.ToBase64String(blob)
        Environment.SetEnvironmentVariable("APP_BLOB", packed)
        Console.WriteLine(packed)
        ' AQIDBAU=
    End Sub
End Module

配置文件遵循同样的形状,值住在 XML 或 JSON 文本里,解码发生在你的启动代码里。给企业角落的一条遗留备注:WCF 和 XML 数据契约把字节数组序列化为 base64Binary XML schema 类型,所以一大批较老的 .NET 服务正是这样存二进制的,而你能在那份 XML 里找到的值,就是朴素的 ToBase64String 输出。

JWT:搭建紧凑形式

紧凑形式的 JSON Web Token 是三段用点分隔的 base64url:头部、载荷和签名。前两段是普通 JSON,第三段是密码学证明,证明持有正确密钥的人造了这个令牌。手工搭建未签名的形状是两次编码加一次字符串拼接,但真正的 JWT 需要签名这一步,一个小小的 HMAC-SHA256 例子能让整件事变得具体:

Imports System
Imports System.Buffers.Text
Imports System.Security.Cryptography
Imports System.Text
Module JwtPacker
    Function BuildHs256Jwt(ByVal headerJson As String, ByVal payloadJson As String, ByVal secret() As Byte) As String
        Dim header As String = Base64Url.EncodeToString(Encoding.UTF8.GetBytes(headerJson))
        Dim body As String = Base64Url.EncodeToString(Encoding.UTF8.GetBytes(payloadJson))
        Dim signingInput As String = header & "." & body
        Using hmac As New HMACSHA256(secret)
            Dim signature() As Byte = hmac.ComputeHash(Encoding.UTF8.GetBytes(signingInput))
            Return signingInput & "." & Base64Url.EncodeToString(signature)
        End Using
    End Function
End Module

拿头部 {"alg":"HS256","typ":"JWT"} 和你自选的载荷跑它,结果就是一个货真价实的紧凑 JWT:任何地方都没有填充,三段全是 URL 安全字符。注意签名也是 base64url,因为整个令牌都得在 URL 或 HTTP 头部里活下来。对生产系统,System.IdentityModel.Tokens.Jwt 包(来自 Microsoft Entra 团队的 IdentityModel 套件)会替你搭建、签名和验证这些令牌,而密钥管理、算法钉死和过期检查正属于那一层。手工滚动编码用于理解和小工具都没问题;对任何守卫访问的东西,让库来承重。

坑:VB 编码器在哪里打滑

这里的陷阱是语言习惯和输出塑造意外的大杂烩,而大多数要价是一次调试会话而不是一次崩溃:

  • Byte 与 Byte()。编码器要的是数组。在 Visual Basic 里单个字节是 Byte,数组是 Byte(),差别就是一对括号。在 Option Strict On 下,猜错是编译错误;关掉它,你可能得到的是一次运行时意外。保持严格模式开着,让括号看得见。
  • Encoding.Default 陷阱,反向版。区域设置分歧的故事是 .NET Framework 的:在现代 .NET 上,Default 永远是 UTF-8,所以同一根字符串在任何机器上编码方式都一样。对任何跨越机器的东西,显式说出编码,通常是 UTF-8 - 这条建议无论如何都成立。
  • CRLF 有路子钻进来。InsertLineBreaks 对 MIME 是绝妙,对 URL、JSON 和数据库文本列则是灾难,在那里它会插入没人要的回车换行。只有当消费者期待折行时才用它,拿不准时用默认的 None
  • 边界处的填充错配。.NET 的 Base64Url 不发出填充,而其他生态里的一些库会加上(还有一些严格的解码器要求它)。当你的编码值跨越生态时,在发出字符串之前确认另一侧的期待;JWT 要的是不带填充的形式,这正是 .NET 的默认值。
  • 往返不是恒等。解码一根带折行和填充的字符串再重新编码,你得到一条带着新鲜填充的干净单行,而不是原文本。如果你的逻辑比较编码值是否相等,改为比较解码后的字节。
  • 尺寸上限是真的。输出长度公式 - 每三个字节四个字符向上取整 - 在大约 15 亿字节输入时就会溢出 32 位计数,编码器会回你一个 OutOfMemoryException,而不是一根半成品字符串。对接近那个量级的输入,改用流(见下文)。
  • span 墙。基于 span 的编码器可以从 VB 在调用点调用:把你的 Byte()Char() 数组直接递进去,编译器会转换它们。但你不能声明类型为 SpanReadOnlySpan 的变量、字段或参数;编译器会以"此编译器版本不支持包含嵌入式引用的类型"拒绝。VB 的惯用法是用普通数组调用 span API,并且永远不存 span。
  • BitConverter 不是 Base64。BitConverter.ToString(bytes) 渲染出成对间用短横线分隔的十六进制,所以它是一个诱人的错误答案,在对方期望 TWFu 的地方产出 4D-61-6E。对 Base64,那个类永远是 System.Convert,每一次都是。

速度与尺寸:性能笔记

Base64 的"缓慢文本编解码"名声撑不过与现代运行时的接触。.NET 里的编码器在机器支持时跑硬件向量化的代码,为 AVX-512、AVX2 和 SSE 指令集配备专用快速路径,AVX-512 路径每步吞掉 48 个字节。对普通负载,经典的 ToBase64String 调用快得让算法很少成为瓶颈;你能感知的成本是 33% 的尺寸税,以及在热路径上的中间分配。如果你要编码百万级小值,基于 span 的 API 是精修:TryToBase64Chars 写进你控制的字符 span,用布尔值报告成功,而 System.Buffers.Text.Base64 更进一步,直接编码进你分配的 UTF-8 缓冲区,甚至原地膨胀数据:

Imports System
Imports System.Buffers
Imports System.Buffers.Text
Imports System.Text
Module BufferPacker
    Sub Main()
        Dim data() As Byte = {1, 2, 3, 4, 5}
        Dim textLength As Integer = Base64.GetMaxEncodedToUtf8Length(data.Length)
        Dim buffer(textLength) As Byte
        Dim written As Integer
        Dim consumed As Integer
        Dim status As OperationStatus = Base64.EncodeToUtf8(data, buffer, consumed, written)
        Dim packed As String = Encoding.ASCII.GetString(buffer, 0, written)
        Console.WriteLine(packed)
        ' AQIDBAU=
    End Sub
End Module

要留意的模式是:你用辅助方法给缓冲区定尺寸,编码进去,再把已使用的前缀转成字符串,这让中间占地面积尽可能小。而对大到让字符串难受的文件,流式搭档让内存保持平坦:包在 CryptoStream 里的 ToBase64Transform 变换分块读你的输入,写出编码文本,所以一个 20 亿字节文件永远不必一口气变成一个 27 亿字节的字符串:

Imports System.IO
Imports System.Security.Cryptography
Module StreamPacker
    Sub EncodeFile(ByVal inputPath As String, ByVal packedPath As String)
        Using inputStream As New FileStream(inputPath, FileMode.Open, FileAccess.Read)
            Using packedStream As New CryptoStream(New FileStream(packedPath, FileMode.Create), New ToBase64Transform(), CryptoStreamMode.Write)
                Dim buffer(65535) As Byte
                While True
                    Dim read As Integer = inputStream.Read(buffer, 0, buffer.Length)
                    If read = 0 Then Exit While
                    packedStream.Write(buffer, 0, read)
                End While
            End Using
        End Using
    End Sub
End Module

一条前瞻备注:预览版 .NET 11 库会在现有 Base64 类型上添加新的便捷和 span 重载,所以如果你的项目能跟上预览,工具箱还在继续长大;如果不能,上面的一切在每个受支持版本上都很稳定。

简史:从 MSXML 到 Span

远在 .NET 之前,需要 Base64 的 Visual Basic 程序从 COM 世界借用它。经典的 VB6 和 VBA 技巧(仍在 Excel 和 Office 里运行的那套宏语言)用的却是一个 XML DOM 元素:MSXML 解析器允许一个节点把 DataType 声明为 bin.base64,于是把你的字节写进节点的 nodeTypedValue,再读回它的 text 属性,你就拿到了编码字符串,真正的 Base64 数学由 DOM 代劳(ADO Stream 对象自己的 Charset 属性只认识 "utf-8" 或 "iso-8859-1" 这样的真字符集名字,不认识 "base64",所以它在转换本身中不扮演任何角色)。它巧妙,它无处不在,而且几十年来它仍是 "base64 VBA" 还在搜索引擎上点亮的原因。那个时代在 2002 年结束:这门语言第一个 .NET 版本 Visual Basic 7.0 加入了新的公共语言运行时,.NET Framework 开箱带来了 System.ConvertToBase64String。从 2003 年的 .NET Framework 1.1 起,每个 VB 程序都能用一个调用编码 Base64,无需注册任何组件。

现代章节很短。2018 年,.NET Core 2.1 加入了分配轻省的 TryToBase64Chars 方法和底层的基于 span 的 System.Buffers.Text.Base64 类。2024 年,.NET 9 把 URL 安全字母表标准化为 Base64Url,终结了十年手工 Replace 调用。截至 2026 年,.NET 10 - 2025 年 11 月发布 - 是承载着这一切的长期支持版本,预览中的 .NET 11 库正在添加新一代便捷方法,所以从 2003 年的一行式到 span 时代,编码器的故事是同一个类变得越来越快、越来越精确,从来不是推倒重来。

趣味事实,VB 版

  • InsertLineBreaks 精确复现了 MIME 76 字符规则,CRLF 在内,这意味着你的编码器在 2026 年写出的换行,与 1990 年代某封邮件标准定义的换行逐字节同形。
  • IsNot 运算符随 Visual Basic 2005 加入,曾作为微软专利申请的主题上过新闻。能享有这份殊荣的语言运算符少之又少。
  • 最初的 Visual Basic 于 1991 年发布,那时万维网还不存在。等到 data URI 方案 1998 年出现时,Base64 已经携带邮件附件五年了,而 VB 早在三年前就长成了 32 位语言,凭的是 1995 年的 Visual Basic 4。
  • 在带 AVX-512 的硬件上,运行时编码器每个向量步处理 48 个字节,这就是博物馆里的查表和工厂里的传送带之间的差别。
  • My 命名空间,Visual Basic 2005 年那层著名的语法糖,从不需要添加 Base64 助手。System.Convert 永远只差一次命名空间导入,这是一个罕见的案例:VB 运行时没有往框架已经讲好的故事里添任何东西。

另一面

本文覆盖了 Visual Basic 中 Base64 的编码一侧:工具箱、输出塑造的决定、URL 安全字母表,以及从文件到 JWT 的用例。反方向 - 拿一条进来的字符串,把它变回它藏着的字节 - 有它自己的一组行为、宽容规则和坑,姊妹站点上的配套解码文章对它做了完整详细的覆盖。通往它的链接就在这行下方,而首页上的工具依然是手工编码小负载最快的方式。

最后更新: 2026-09-08

相关文章: Visual Basic 中的 Base64 解码:完整指南