使用 T-SQL 实现 base64 解码

复制代码
IF OBJECT_ID(N'dbo.f_base64_decode'IS NOT NULL
    
DROP FUNCTION dbo.f_base64_decode;
GO

/*-- == base64 解码=================================
    在SQL Server 中,使用FOR XML 生成xml 实例时,binary 数据
使用base64 编码,而解释xml 的时候,却没有相应的解码方法。
    使用此函数可以解决这个问题
   
    Base64 编码把个位字节(*8=24)转化为个位的字节(*6=24)
之后在位的前面补两个,形成位一个字节的形式。用下面的个字符重新
表示:“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”
    如果输入的数据的长度不是的倍数,则编码结果的不足部分用等号“=”
补足。
 
---------------------------------------------------------
-- 调用示例
 
    SELECT -- 还原成字符串
       v1 = CONVERT(varchar(max), v1),
       v2 = CONVERT(nvarchar(max), v2)
    FROM(
       SELECT  -- 解码base64 编码
           v1 = dbo.f_base64_decode(v1),
           v2 = dbo.f_base64_decode(v2)
       FROM(  -- 通过for xml 生成base64 编码
           SELECT
             v1 = (SELECT CONVERT(varbinary(max), 'base64 test') FOR XML PATH(''), TYPE).value('/', 'nvarchar(max)'),
              v2 = (SELECT CONVERT(varbinary(max), N'base64 解码测试') FOR XML PATH(''), TYPE).value('/', 'nvarchar(max)')
       )DATA
    )A
 
---------------------------------------------------------
-- 环境要求
 
适用于sql server 2005 或者更高的版本

-- ==== 邹建.02(引用请保留此信息) =============== 
*/
CREATE FUNCTION dbo.f_base64_decode(
    
@input varchar(max)
)
RETURNS varbinary(max)
AS
BEGIN
    
DECLARE
       
@base64 char(64),
       
@pos int,
       
@len int,
       
@output varbinary(max);
 
    
SELECT
       
@base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
       
@pos = 1,
       
@len = LEN(@input),
       
@output = 0x;
 
    
IF @input = ''
       
RETURN 0x;
 
    
IF @len % 4 > 0 OR @len IS NULL
       
RETURN NULL;
      
    
WHILE @pos < @len
    
BEGIN
       
SELECT
           
@output = @output
              
+ CONVERT(binary(1), ((v1 & 63* 4 ) | ((v2 & 48/ 16))
              
+ CONVERT(binary(1), ((v2 & 15* 16| ((v3 & 60/ 4 ))
              
+ CONVERT(binary(1), ((v3 & 3 ) * 64| ((v4 & 63/ 1 )),
           
@pos = @pos + 4
       
FROM(
           
SELECT
              v1 
= CHARINDEX(SUBSTRING(@input@pos + 01) COLLATE Chinese_PRC_BIN, @base64- 1,
              v2 
= CHARINDEX(SUBSTRING(@input@pos + 11) COLLATE Chinese_PRC_BIN, @base64- 1,
              v3 
= CHARINDEX(SUBSTRING(@input@pos + 21) COLLATE Chinese_PRC_BIN, @base64- 1,
              v4 
= CHARINDEX(SUBSTRING(@input@pos + 31) COLLATE Chinese_PRC_BIN, @base64- 1     
       )A;
    
END;
 
    
RETURN(SUBSTRING(@output1@len / 4 * 3 - 3 + CHARINDEX('='RIGHT(@input2+ '=')));
END;
GO
复制代码


posted @   wenanry  阅读(3787)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
点击右上角即可分享
微信分享提示