【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据

时间过的真快,这是导师回顾新星计划学习的第六篇文章!
最近这段时间非常忙,虽然导师首次参与新星计划活动已经在4月16日圆满结束,早想腾出时间来好好整理活动期间分享的知识点。
非常感谢大家的支持和活动期间的文章输出,导师也是忙里抽空给大家准备分享的内容,也是尽力了,所以分享的知识点主要是偏向于基础和基本的实战,虽然不是讲解的很系统,但是能够了解到一定的实战信息
期待我们的下次学习,导师将会在6月或者7月再次发起新星计划,本次活动也得到学员和平台的肯定,平台也是非常欢迎导师再次发起新星计划,非常感谢!

目录

  • 1、MD5
    • 1.1、基本概念
    • 1.2、碰撞破解
    • 1.3、场景使用
  • 2、知识点
    • 2.1、函数分类
    • 2.2、自定义函数
      • 2.2.1、标量值函数
      • 2.2.2、表值函数
      • 2.2.3、修改函数
    • 2.3、存储过程
      • 2.3.1、创建无参数存储过程
      • 2.3.2、创建有参数存储过程
      • 2.3.3、修改存储过程
  • 3、模拟数据
    • 3.1、创建MD5数据表
    • 3.2、创建MD5标志表
    • 3.3、取值范围函数
    • 3.4、创建存储过程

  • 计划
    【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第1张图片

1、MD5

1.1、基本概念

1)MD5的全称,Message-Digest Alg orithm5(信息-摘要算法),在90年代初由Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。
2)MD5是一种散列(Hash)算法,散列算法的用途不是对明文加密,目的是让人看不懂,而是通过对信息摘要的比对,防止对原文的篡改。通常对散列算法的“破解”,就是找碰撞。

1.2、碰撞破解

简单的理解,就是通过穷举明文,通过明文加密和当前密文进行对比,如果对比相同值则碰撞破解成功。

1.3、场景使用

说实在的,挺佩服这家公司公司的,就像它页面那句话,本站对于md5、sha1、mysql、ntlm等的实时解密成功率在全球遥遥领先。成立17年,一直被抄袭,从未被超越。运行17年,累计加密数据超过500TB,超过90万亿条记录。
【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第2张图片

2、知识点

2.1、函数分类

上一次已经提到过,常见的函数有如下几种:表值函数、标量值函数、聚合函数、系统函数。
这里只简单讲解常见的【系统函数(内置函数)】中的【聚合函数】和【日期和时间函数】,如下图
感兴趣的小伙伴可以查看导师这篇文章:https://blog.csdn.net/lmy_520/article/details/106016101

  • 聚合函数
    【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第3张图片
  • 日期和时间函数
    【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第4张图片

2.2、自定义函数

关键词:function
上一篇我们也简单讲解了自定义函数的作用和优势,以下再提一下
1)用于计算复杂逻辑,可以返回单个标量值或者结果集
2)能够接收传入参数,单不能输出传出参数
3)优点,模块化、执行速度更快、减少网络流量
如果在程序之间执行,特别是跨服务器数据库,每次需要把一大串执行sql语句通过网络传到目标服务器数据库是需要消耗比较大的流量,
所以定义成函数自然就减少了很多sql语句传送,直接就是一个函数名搞定

2.2.1、标量值函数

  • 代码
-- 创建标量值函数
go
    create function constData(@test int) returns int
    as
    begin
    -- 写自己的逻辑
    set @test+=1
    return @test
    end
go

-- 调用
declare @testValue int
set @testValue=1
select dbo.constData(@testValue) as 返回值
  • 效果
    【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第5张图片

2.2.2、表值函数

  • 方式一
-- 定义
create function funcName (@a int) returns table
as
return select top 10 studentName from student_score_20wan

-- 调用
select * from funcName(1)
  • 方式二
go
create function consTable(@test int) returns @tempTable table
(studentName nvarchar(50))
as
begin
    -- 写自己的逻辑
    insert into @tempTable(studentName)
    select top 10 studentName from student_score_30wan
end
go

-- 调用
select * from constTable(1)
  • 两种方式返回的效果
    【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第6张图片
  • 温馨提示
    详细可查看官方解释:https://learn.microsoft.com/zh-cn/sql/relational-databases/user-defined-functions/user-defined-functions?view=sql-server-ver16

2.2.3、修改函数

1)可视化界面修改
【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第7张图片
2)sql语句进行修改
通过上一步可视化界面点击修改后,同样也是跳转到sql语句界面,在界面可以查看修改使用了alter关键词
【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第8张图片

原则:Write Less Do More!
简介:一只喜欢全栈方向的程序员,专注基础和实战分享,欢迎咨询,尽绵薄之力答疑解惑!

2.3、存储过程

关键词:proc
简单理解,存储过程的主要作用就是更加灵活集中处理各类简单或复杂场景功能,可以有入参和出参,以及获得结果集合。
存储过程优点
1)运行速度快,创建时已经编译,更加安全高效
2)可以编写更加复杂的数据库操作
3)更加能够节省网络流量,一般复杂sql语句肯定会写很多,如果每次都是通过网络传送,那必定消耗很大流量

2.3.1、创建无参数存储过程

可以先判断是否存在,不存在则创建,否则移除再创建或者其他操作
1)格式
create proc 名称
2)代码

-- 创建无参存储过程
if (exists (select * from sys.objects where name = 'proc_myProcOne'))
    drop proc proc_myProcOne
go
create proc proc_myProcOne
as
select top 10 * from student_score

-- 执行存储过程
exec proc_myProcOne;

3)效果
【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第9张图片

2.3.2、创建有参数存储过程

1)格式
create proc 名称(参数1,参数2,…)
2)代码

-- 创建多个参存储过程
if (exists (select * from sys.objects where name = 'proc_more_myProcOne'))
    drop proc proc_more_myProcOne
go
create proc proc_more_myProcOne(
    @studentName nvarchar(50),
    @courseName nvarchar(50)
)
as
select top 10 * from student_score 
where studentName=@studentName and courseName=@courseName

-- 执行存储过程
exec proc_more_myProcOne '陈珊歆','语文';

3)效果
【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第10张图片

2.3.3、修改存储过程

通过可以通过可视化界面修改,跳转到sql语句
【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第11张图片

3、模拟数据

3.1、创建MD5数据表

本次是模拟添加MD5数据,因此表设计如下
基本字段:自增编号、Guid编号、添加时间
表字段:md5加密值,md5密文值、md5长度

create table md5_data_eight
(
    id int identity(1,1) primary key,
    guid_value varchar(50),
    md5_plaintext varchar(100),        -- 明文
    md5_ciphertext varchar(100),    -- 密文
    md5_length int,                    -- 明文长度
    add_time datetime
)

3.2、创建MD5标志表

主要用于记录当前加密到那个组合,就不需要每次都是从第一次开始,比如00000000
只需要每次调用函数时,能够返回当前组合的明文值,然后再在存储过程里对明文进行加密

create table md5_data_eight_flag
(
    id int identity(1,1) primary key,
    p1 int,
    p2 int,
    p3 int,
    p4 int,
    p5 int,
    p6 int,
    p7 int,
    p8 int,
    add_time datetime,                    -- 明文长度
    update_time datetime
)

-- 创建完表后,初始化一条记录
insert into md5_data_eight_flag(p1,p2,p3,p4,p5,p6,p7,p8,add_time,update_time)
values(1,1,1,1,1,1,1,1,getdate(),getdate())

3.3、取值范围函数

1)字母大小写,az和AZ,26+26=52个值
2)阿拉伯数字,0~9,10个值
总共加起来就是52+10=62个值,根据8位长度组合规则,一共有多少总组合?
总共组合值等于62的8次方,组合值=Math.pow(62,8)=218340105584896
在这里插入图片描述
3)通过上面,基数太大,重新调整下取值范围,直接纯数字加密
总共组合值等于10的8次方=Math.pow(10,8)=100000000=1亿条记录

  • 代码
    主要注意返回的字符串,必须加上返回长度,否则可能回只返回一位

-- 定义函数:返回表变量结果集

go
    create function getCurrentPlaintext() returns varchar(8)
    as
    begin
        -- 写自己的逻辑
        -- 定义表变量
        declare @tempTable table(
            id int identity(1,1) primary key, 
            value nvarchar(1)
        )
        
        insert into @tempTable values
        ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9')
        
        declare @p1 int
        declare @p2 int
        declare @p3 int
        declare @p4 int
        declare @p5 int
        declare @p6 int
        declare @p7 int
        declare @p8 int
        select @p1=p1,@p2=p2,@p3=p3,@p4=p4,
        @p5=p5,@p6=p6,@p7=p7,@p8=p8
        from md5_data_eight_flag

        declare @plaintext varchar(8)
        set @plaintext=''
        select @plaintext+=[value] from @tempTable where id=@p1
        select @plaintext+=[value] from @tempTable where id=@p2
        select @plaintext+=[value] from @tempTable where id=@p3
        select @plaintext+=[value] from @tempTable where id=@p4
        select @plaintext+=[value] from @tempTable where id=@p5
        select @plaintext+=[value] from @tempTable where id=@p6
        select @plaintext+=[value] from @tempTable where id=@p7
        select @plaintext+=[value] from @tempTable where id=@p8
        --print('第一个明文组合:'+@plaintext)

        return @plaintext
    end
go

3.4、创建存储过程

在使用这条语句保存到表时,会发现是乱码,如下
【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第12张图片

  • 解决方法
    直接在convert后面加多一个参数2即可,可以复制加密串到在线解密网站进行验证
    【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第13张图片
  • 完整代码

go
create proc proc_addMd5
as
begin
    
    declare @plaintext varchar(8)
    declare @ciphertext varchar(100)
    
    select @plaintext=dbo.getCurrentPlaintext()
    --print(@plaintext)

    declare @p1 int
    declare @p2 int
    declare @p3 int
    declare @p4 int
    
    declare @p5 int
    declare @p6 int
    declare @p7 int
    declare @p8 int

    select @p1=p1,@p2=p2,@p3=p3,@p4=p4,
    @p5=p5,@p6=p6,@p7=p7,@p8=p8
    from md5_data_eight_flag

    -- 第一位
    if (@p1+1)>10 begin
        set @p1=1
        
        -- 第二位
        if @p2>10 begin
            set @p2=1

            -- 第三位
            if @p3+1>10 begin
                set @p3=1

                -- 第四位
                if @p4>10 begin
                    set @p4=1

                    -- 第五位
                    if @p5>10 begin
                        set @p5=1

                        -- 第六位
                        if @p6>10 begin
                            set @p6=1

                            -- 第七位
                            if @p7>10 begin
                                set @p7=1

                                -- 第八位
                                if @p8>10 begin
                                    set @p8=8
                                end
                                else begin
                                    set @p8+=1
                                end
                            end
                            else begin
                                set @p7+=1
                            end
                        end
                        else begin
                            set @p6+=1
                        end
                    end
                    else begin
                        set @p5+=1
                    end
                end
                else begin
                    set @p4+=1
                end
            end
            else begin
                set @p3+=1
            end
        end
        else begin
            set @p2+=1
        end
    end
    else begin
        set @p1+=1
    end
    
    
    -- 添加一条记录
    select @ciphertext=convert(varchar(100),HashBytes('md5',@plaintext),2)
    insert into md5_data_eight(guid_value,md5_plaintext,md5_ciphertext,md5_length,add_time)
    values(newid(),@plaintext,@ciphertext,8,getdate())

    -- 更新下一个明文标识
    /*print(@p1)
    print(@p2)
    print(@p3)
    print(@p4)
    print(@p5)
    print(@p6)
    print(@p7)
    print(@p8)*/
    update md5_data_eight_flag set 
    p1=@p1,p2=@p2,p3=@p3,p4=@p4,p5=@p5,p6=@p6,p7=@p7,p8=@p8,
    update_time=getdate()
    where id=1
end
  • 效果
    【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第14张图片
  • 简单一点的方式模拟数据
declare @count int
set @count=1000000
while @count>0 begin
    set @count-=1
    exec dbo.proc_addMd5
end

【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据_第15张图片

本篇到此结束,感谢阅读的小伙伴,打个小小的ad,欢迎关注导师的公众号【有趣小馆】,导师会时不时发布一些有趣好玩的功能,欢迎关注!

你可能感兴趣的:(sql,server,sql,server,md5,自定义函数,存储过程,模拟数据)