散列算法和数字签名笔记

散列算法与数字签名

在RSA加密中,如果A是发送方,B是接受方,则A用B的公钥加密信息,而B可以用自己的私钥解密信息,从而达到保密传输的作用。

但是在数字签名技术中,这个过程恰好是反过来的,即:A是发送方,B是接收方,A用自己的私钥加密信息,B用A的公钥解密信息。因为A的私钥只有A持有,所以如果B使用A的公钥成功解密信息,则可以证明是A发来的信息。即使中间有人用A的公钥解密后篡改了信息,由于没有私钥,从而无法完成对篡改后信息的加密,这样B也不会认为被篡改后的信息是A发过来的。

尽管这个机制无法完成保密(因为所有人都可以拿到对应的公钥并解密信息),但它的目的是进行鉴别(标识和证明A是发送方)。

消息摘要(message digest)\散列(hash)

消息摘要,也称哈希,是消息的指印或汇总,通常用于校验数据的完整性。消息摘要采用的原理和CRC、LRC类似,但范围会更大。假设一个摘要算法是除以1000,对于数字4000来说摘要就是4,如果改变了4000,得到的摘要就不再是4。并且如果只给出4而不给出摘要算法,则无法追溯源数字4000(当然一个合格的算法就是知道了也不会从摘要追溯到原文的,这个就是个例子)。且通常摘要算法会比原文小很多。

消息摘要的要求可以总结如下:

  1. 给定一个信息,应很容易求出消息摘要,并且无论何时,同一个消息求得的摘要都是相同的
  2. 给定消息摘要,应难以求出原先的信息
  3. 给定两个消息,求出的消息摘要应不同

如果两个消息得到相同的消息摘要,则会违背上述原则,称为冲突(collision)。消息摘要机制应最大程度的保证:对于一个消息(M1)及其消息摘要(MD),不太可能找到另一个消息(M2)可以产生完全相同的消息摘要。

Merkle–Damgård构造

在这里插入图片描述

简单来说,Merkle–Damgård算法的流程如下:

  1. 把消息划分为n个消息块
  2. 对最后一个消息块做长度填充
  3. 每个消息块都会和一个输入向量做一个运算,把这个计算结果当成下个消息块的输入向量

下面的MD5和SHA系列的哈希算法都是基于该结构进行设计的。

MD5算法

MD5消息摘要算法是Ron Rivest开发的。MD5前面还有4版,因为比较脆弱而被放弃(MD4甚至没有发布)。MD5速度很快,产生128位消息摘要。

工作原理
  1. 初始化

    1. 填充

      在原消息后增加填充位,目的是使元消息长度等于一个值( 512 ∗ k − 64 512*k-64 512k64,k为任意整数)。填充方法是固定的,第一位为1其它位为0。并且即使原消息已经是 512 ∗ k − 64 512*k-64 512k64位,也要再增加512位。

    2. 增添填充位后,下一步要计算消息原长,将其加进填充后的消息末尾

      先计算消息长度,不包括填充位,然后把这个消息原长表示为64位值,添加到加进填充后的消息末尾。如果消息长度无法用64位来表示(长度大于 2 64 2^{64} 264位),就只用长度的低64位(取后64位,或者也可以看做 长 度 % 2 64 长度\%2^{64} %264)。

      增添消息长度后,该消息的位数就是512的倍数了,成为要散列的消息(格式为:原文+填充+原文长度)。

    3. 将输入分成512位的块

      处理后的信息长度位512k,所以可以分为k个512位的块

    4. 初始化链接变量

      链接变量

      A十六进制01234567
      B十六进制89ABCDEF
      C十六进制FEDCBA98
      D十六进制76543210

      注:由于程序中采用的是Little-Endian方式存储数据,所以在程序中A应该表示为0x67452310,B、C、D同理。

  2. 处理块

    这个算法是一个循环,对消息的多个512位块运行

    1. 将四个链接变量复制到四个变量a,b,c,d中,使a=A,b=B,c=C,d=D。

    2. 将当前的512位块分解为16个子块,每个子块为32位

    3. 针对每一个512块(16个 32位子块)有四轮的处理:

      第一轮函数 F ( x , y , z ) = ( x ∧ y ) ∨ ( ¬ x ∧ z ) F(x,y,z)=(x\wedge y)\vee (\neg x\wedge z) F(x,y,z)=(xy)(¬xz)

      第二轮函数 G ( x , y , z ) = ( x ∧ z ) ∨ ( y ∧ ¬ z ) G(x,y,z)=(x\wedge z)\vee(y\wedge\neg z) G(x,y,z)=(xz)(y¬z)

      第三轮函数 H ( x , y , z ) = x ⊕ y ⊕ z H(x,y,z)=x\oplus y\oplus z H(x,y,z)=xyz

      第四轮函数 I ( x , y , z ) = y ⊕ ( x ∨ ¬ z ) I(x,y,z)=y\oplus (x\vee\neg z) I(x,y,z)=y(x¬z)

      在此基础上,有函数可以表示一轮的运算: a = b + C L S s ( a + g ( b , c , d ) + X [ k ] + T [ i ] ) a=b+CLS_s(a+g(b,c,d)+X[k]+T[i]) a=b+CLSs(a+g(b,c,d)+X[k]+T[i])

      其中g是四个逻辑函数之一, C L S s CLS_s CLSs表示循环左移s位,该函数表明,一轮中共有 16次运算(分别按对应的顺序将该512块的16个子块全部带入运算),每一次运算都只改变当前次运算中的a的值,而不改变b,c,d。该次运算结束后,将运算得到的a,b,c,d的值循环右移(即a,b,c,d=d,a,b,c)后即是这一次运算的输出,也作为下一轮的a,b,c,d输入。该轮16次运算完成后,将最后输出的a,b,c,d与第一轮输入的a,b,c,d相加得到这一轮最终的a,b,c,d,然后作为下一轮的输入参与下一步的运算。直到最后运算完成,最终得到的四个链接变量按照顺序排列即是所求的MD5消息摘要。

  3. 一些剩下的表格

    流程图(一轮中的一次)

在这里插入图片描述

MD5与MD4
特性MD4MD5
轮数34
常亮的使用所有迭代中相同所有迭代中不相同
第二轮的处理p ( b ∨ c ) ∧ ( b ∨ d ) ∧ ( c ∨ d ) (b\vee c)\wedge (b\vee d)\wedge(c\vee d) (bc)(bd)(cd) ( b ∨ d ) ∧ ( c ∨ ( ¬ d ) ) (b\vee d)\wedge (c\vee (\neg d)) (bd)(c(¬d))

此外,第2轮和第3轮访问子块的顺序也发生改变,引入了更大的随机性。

MD5的抗攻击性

注:该算法已被我国王小云教授攻破

安全散列算法(SHA系列算法)

SHA-1

该算法有美国国家标准与技术协会(NIST)和NSA共同开发了安全散列算法(SHA,Secure Hash Alogorithm)。1993年,SHA以联邦信息处理标准(FIPS PUB 180,即通常所说的SHA-0)的形式发布,95年修订为FIPS PUB 180-1,后更名为SHA-1。SHA-1是在MD4的基础上修改而成的,与MD4设计非常相像。

SHA(应该是SHA-1)可以处理长度在 a 64 a^{64} a64以内的任何输入消息。SHA的输出是消息摘要,长度为160位(多于MD5的128位)

工作原理

SHA-1的工作原理与MD5类似

  1. 初始化(此处前三步与MD5一样)

    1. 填充

    2. 添加长度

    3. 将输入分为512位块

    4. 初始化链接变量

      由于SHA-1的输出比MD5多32位,所以相应的连接变量比MD5也要多一个。链接变量A-D与MD5相同,E初始化为十六进制的c3d2e1f0

  2. 处理块

    1. 将链接变量复制到abcde中组成寄存器,存储中间和最后的结果

    2. 将当前块分为16个32位块

    3. SHA共四轮,每一轮20步。每一轮三个输入为当前512位块(不是一次输入完)、寄存器abcde和常量K[t],t为0~79

      轮次t值范围K[t]的值,十六进制K[t]的值,十进制(整数部分)
      11~195A 92 79 99 2 30 × 2 2^{30}\times \sqrt2 230×2
      220~396E D9 EB A1 2 30 × 3 2^{30}\times \sqrt3 230×3
      340~599F 1B BC DC 2 30 × 5 2^{30}\times \sqrt5 230×5
      460~79CA 62 C1 D6 2 30 × 10 2^{30}\times \sqrt{10} 230×10
    4. SHA的一次迭代操作如图

    在这里插入图片描述

    1. s t s^t st的意思是将32位块循环左移t位

    2. 处理P

      轮次处理P
      1 ( b ∧ c ) ∨ ( ( ¬ b ) ∧ d ) (b\wedge c)\vee ((\neg b)\wedge d) (bc)((¬b)d)
      2 b ⊕ c ⊕ d b\oplus c\oplus d bcd
      3 ( b ∧ c ) ∨ ( b ∧ d ) ∨ ( c ∧ d ) (b\wedge c)\vee (b\wedge d)\vee (c\wedge d) (bc)(bd)(cd)
      4 b ⊕ c ⊕ d b\oplus c\oplus d bcd
    3. W[t]的值是从当前需要输入的32位块求出的32位值,计算如下:

      对W的前16个字(t=0~15 ),就分别依次等于该512块分成的16个子块。

      对W的后64个字(t=16~79),就等于 s 1 ( W [ t − 3 ] ⊕ W [ t − 8 ] ⊕ W [ t − 14 ] ⊕ W [ t − 16 ] ) s^1(W[t-3]\oplus W[t-8]\oplus W[t-14]\oplus W[t-16]) s1(W[t3]W[t8]W[t14]W[t16])

    4. 在这里插入图片描述在这里插入图片描述

历史沿革
SHA-2

NIST发布了三个额外的SHA变体,这三个函数都将讯息对应到更长的讯息摘要。以它们的摘要长度(以位元计算)加在原名后面来命名:SHA-256,SHA-384和SHA-512。它们发布于2001年的FIPS PUB 180-2草稿中,随即通过审查和评论。包含SHA-1的FIPS PUB 180-2,于2002年以官方标准发布。2004年2月,发布了一次FIPS PUB 180-2的变更通知,加入了一个额外的变种SHA-224",这是为了符合双金钥3DES所需的金钥长度而定义。

SHA-256和SHA-512是很新的杂凑函数,前者以定义一个word为32位元,后者则定义一个word为64位元。它们分别使用了不同的偏移量,或用不同的常数,然而,实际上二者结构是相同的,只在循环执行的次数上有所差异。SHA-224以及SHA-384则是前述二种杂凑函数的截短版,利用不同的初始值做计算。

这些新的杂凑函数并没有接受像SHA-1一样的公众密码社群做详细的检验,所以它们的密码安全性还不被大家广泛的信任。Gilbert和Handschuh在2003年曾对这些新变种作过一些研究,声称他们没有找到弱点。

SHA-0破解

在CRYPTO 98上,两位法国研究者提出一种对SHA-0的攻击方式:在261的计算复杂度之内,就可以发现一次碰撞(即两个不同的讯息对应到相同的讯息摘要);这个数字小于生日攻击法所需的2的80次方,也就是说,存在一种算法,使其安全性不到一个理想的杂凑函数抵抗攻击所应具备的计算复杂度。

2004年时,Biham和 Chen也发现了SHA-0的近似碰撞,也就是两个讯息可以杂凑出几乎相同的数值;其中162位元中有142位元相同。他们也发现了SHA-0的完整碰撞(相对于近似碰撞),将本来需要80次方的复杂度降低到62次方。

2004年8月12日,Joux, Carribault, Lemuet和Jalby宣布找到SHA-0算法的完整碰撞的方法,这是归纳Chabaud和Joux的攻击所完成的结果。发现一个完整碰撞只需要251的计算复杂度。他们使用的是一台有256颗Itanium2处理器的超级电脑,约耗80,000 CPU工时。

2004年8月17日,在CRYPTO 2004的Rump会议上,王小云,冯登国、来学嘉,和于红波宣布了攻击MD5、SHA-0 和其他杂凑函数的初步结果。他们攻击SHA-0的计算复杂度是2的40次方,这意味着他们的攻击成果比Joux还有其他人所做的更好。请参见MD5 安全性。2005年二月,王小云和殷益群、于红波再度发表了对SHA-0破密的算法,可在2的39次方的计算复杂度内就找到碰撞。

SHA-1破解

鉴于SHA-0的破密成果,专家们建议那些计划利用SHA-1实作密码系统的人们也应重新考虑。在2004年CRYPTO会议结果公布之后,NIST即宣布他们将逐渐减少使用SHA-1,改以SHA-2取而代之。

2005年,Rijmen和Oswald发表了对SHA-1较弱版本(53次的加密循环而非80次)的攻击:在2的80次方的计算复杂度之内找到碰撞。

2005年二月,王小云、殷益群及于红波发表了对完整版SHA-1的攻击,只需少于2的69次方的计算复杂度,就能找到一组碰撞。(利用生日攻击法找到碰撞需要2的80次方的计算复杂度。)

这篇论文的作者们写道;“我们的破密分析是以对付SHA-0的差分攻击、近似碰撞、多区块碰撞技术、以及从MD5算法中寻找碰撞的讯息更改技术为基础。没有这些强力的分析工具,SHA-1就无法破解。”此外,作者还展示了一次对58次加密循环SHA-1的破密,在2的33次方个单位操作内就找到一组碰撞。完整攻击方法的论文发表在2005年八月的CRYPTO会议中。

殷益群在一次面谈中如此陈述:“大致上来说,我们找到了两个弱点:其一是前置处理不够复杂;其二是前20个循环中的某些数学运算会造成不可预期的安全性问题。”

2005年8月17日的CRYPTO会议尾声中王小云、姚期智、姚储枫再度发表更有效率的SHA-1攻击法,能在2的63次方个计算复杂度内找到碰撞。

2006年的CRYPTO会议上,Christian Rechberger和Christophe De Cannière宣布他们能在容许攻击者决定部分原讯息的条件之下,找到SHA-1的一个碰撞。

在密码学的学术理论中,任何攻击方式,其计算复杂度若少于暴力搜寻法所需要的计算复杂度,就能被视为针对该密码系统的一种破密法;但这并不表示该破密法已经可以进入实际应用的阶段。

消息鉴别码(MAC)

消息鉴别码(Message Authentication Code)的概念类似于消息摘要,但是消息摘要只是简单的消息指印,不涉及加密过程,但MAC要求发送发和接收方知道共享的对称秘钥,用其准备MAC

基本使用的流程图

在这里插入图片描述

HMAC(Hash-based Message Authentication Code基于哈希/散列的消息鉴别码)

近年来,人们越来越多地利用杂凑函数来设计MAC,因为杂凑函数执行通常要快于对称分组密码。在目前所提出的基于杂凑函数的消息认证算法中,HMAC算法(RFC2104)是实际使用中使用最多的方案

HMAC是Internet协议(IP)安全的强制安全实施方法,并在Internet上广泛使用的安全套接层(SSL)协议中使用。其基本思想是复用MD5等现有的消息摘要算法。因此,HMAC利用消息摘要算法,把消息摘要坎组偶一个黑盒子,用共享的密钥加密信息摘要,从而输出MAC。如图:

在这里插入图片描述

工作原理

涉及到的变量:

​ MD:使用的消息摘要函数(例如MD5)

​ M:计算MAC的输入消息

​ L:消息M的块数

​ b:每一块的位数

​ K:HMAC使用的共享对称密钥

​ ipad:字符串00110110重复b/8次

​ opad:字符串01011010重复b/8次

步骤:

  1. 使K的长度等于b

    1. K<b:扩展密钥K,使得K的长度等于b(原一个信息块的位数)。为此,在K左边加上足够的0。比方说,哈希算法为MD5,那么一个信息块为512位。若初始密钥为170位,那么在该密钥左边加上342个0
    2. K=b,无操作
    3. K>b,这时应当缩减K与b的位数相同。方法是使K通过为该HMAC例子选择的消息摘要算法MD,从而得到处理过的b位密钥
  2. K与ipad异或操作,得到S1

  3. 将M添加到S1末尾

  4. 消息摘要算法

    对于第3步的输出(S1+M的组合)采用选择的消息摘要算法,该输出为H

  5. K与opad异或,得到S2

  6. 将H添加到S2后

  7. 消息摘要算法

    对第6步的输出采用选择的消息摘要算法,该步操作输出的即是最终的MAC

图例:在这里插入图片描述

HMAC对应的应该是MAC里面用函数和密钥K求MAC的那一步的详细过程。

缺点
  1. HMAC中假设只有发送方和接收方知道的对称密钥如何分配,即密钥分配问题
  2. HMAC不适用于多个接收方的情形。因为使用的是对称密钥,难以对多个接收方进行发送,如果多方共用一个对称密钥,那么产生下面的问题
  3. 如果多方共享对称密钥,如何确保消息的来源是发送方而不是其它的接收方。因为对称密钥是一样的,其它接收方也可以以发送方的身份发送假消息
  4. 在只有两方的场合中,如果到了需要用消息当做证据的时候,如何证明该消息是发送方生成的,而不是由接收方生成的(对称密钥两个人都有,都可以生成MAC),而这个问题是致命的。

数字签名技术

由于前面所述的MAC的相关问题,所以出现了用于数字签名的数字签名标准(DSS,Digital Signature Standard)。91年,美国国家标准与技术学会(NIST)发布了DSS标准,作为FIPS(联邦信息处理标准)PUB 186,并于1993和1996年进行了修订。DSS利用SHA-1算法计算原消息的消息摘要,并对信息进行数字签名(利用数字签名算法DSA)。DSS是一个标准,而DSA是一个算法。

RSA数字签名

假设发送方(A)向接收方(B)发一个消息(M),并对消息(M)计算数字签名(S)

过程:

  1. 发送方A用SHA-1对M计算消息摘要(MD1)
  2. 发送方用私钥加密这个消息概要,这个过程的输出是A的数字签名(DS)
  3. 发送方(A)将消息(M)和数字签名(DS)一起发给接收方(B)
  4. 接收方(B)收到消息(M)和发送方的数字签名后,使用与A相同的消息摘要算法计算消息摘要(MD2)
  5. 接收方(B)用发送方的公钥解密(也称为设计)数字签名。注意A用私钥加密消息摘要,得到数字签名,因此只能用A的公钥解密。这个过程得到原先的消息概要,和第一步A求出的一样
  6. 这时B比较两个消息概要MD1(第5步从A的数字签名中求出)和MD2(第4步求出),若MD1=MD2,则可以表明:
    1. B也接受原消息M,是A发来的正确消息,未经修改
    2. B也保证消息来自A而不是别人伪装的A

DSA与数字签名

该算法是基于离散对数困难性设计而成

初始化

所需变量:

​ p:长度为L位的素数,L是在512~1024之间的64位的倍数。原标准中,p总是512位,但受到了许多的技术批评,所以NIST做出了改变

​ q:(p-1)的160位素数因子

​ g: 1 < h < p − 1 1<h<p-1 1<h<p1 g ≡ h ( p − 1 ) / q m o d   p g\equiv h^{(p-1)/q}mod\ p gh(p1)/qmod p,且 h ( p − 1 ) / q m o d   p h^{(p-1)/q}mod\ p h(p1)/qmod p>1​

​ x:(1,q)​的一个随机数

​ y: y ≡ g x %   p y\equiv g^x \%\ p ygx% p

​ H:消息摘要算法(通常是SHA-1)

前三个变量p,q,g是公开的,x是私钥,y是公钥

签名产生过程

用户随机选择一个 k ∈ ( 0 , q ) k\in (0,q) k(0,q)。用户对消息M的签名为(r,s),其中 r ≡ ( g k m o d   p ) m o d   q r\equiv (g^k mod\ p)mod\ q r(gkmod p)mod q s ≡ [ k − 1 ( H ( M ) + x r ) ] m o d   q s\equiv [k^{-1}(H(M)+xr)]mod\ q s[k1(H(M)+xr)]mod q,H(M)是根据SHA-1求出的杂凑值。

签名验证过程

设接收方收到的消息为 M ′ M' M ,签名为 ( r ′ , s ′ ) (r',s') (r,s)。计算

\begin{equation}
\begin{aligned}
w\equiv (s')^{-1}mod\ q,u_1\equiv[H(M')w]mod\ q \\ 
u_2\equiv r'w\ mod\ q,\ v\equiv [g^{u_1}y^{u_2}\ mod\ p]mod\ q
\end{aligned}
\end{equation}

检查 v = r ′ v=r' v=r​是否成立,若成立,则认为签名有效。这是因为若 ( M ′ , r ′ , s ′ ) = ( M , r , s ) (M',r',s')=(M,r,s) (M,r,s)=(M,r,s),则有

\begin{equation}
\begin{aligned}
v&\equiv [(g^{H(M)w}y^{r'w})mod\ p]mod\ q \\
&\equiv[(g^{H(M)w}g^{xrw})mod\ p]mod\ q \\
&\equiv[(g^{(H(M)+xr)s^{-1}}mod\ p]mod\ q \\
&\equiv(g^kmod\ p) \\
&\equiv r
\end{aligned}
\end{equation}

上面式子中有四个函数,分别是:

\begin{equation}
\begin{aligned}
&s\equiv f_1[H(M),k,x,r,q]\equiv[k^{-1}(H(M)+xr)]mod\ q \\
&r\equiv f_2(k,p,q,g)\equiv (g^kmod\ p)mod\ p \\
&w\equiv f_3(s',q)\equiv (s')^{-1}mod\ q \\
&v\equiv f_4[y,q,g,H(M),w,r']\equiv [(g^{(H(M')w)mod\ q}y^{r'w\ mod\ q})mod\ p]mod\ q 
\end{aligned}
\end{equation}`
渲染不出来,公式太复杂,就把代码放这了

这个算法在签名产生过程中的运算主要是求r的模指数运算 r ≡ f 2 ( k , p , q , g ) ≡ ( g k m o d   p ) m o d   p r\equiv f_2(k,p,q,g)\equiv (g^kmod\ p)mod\ p rf2(k,p,q,g)(gkmod p)mod p,而这一运算与待签的消息无关,因此能被预先计算。事实上,用户可以事先计算出许多的 r r r k − 1 k^{-1} k1待用,加快签名产生的速度。

哈希长度扩展攻击

参考资料:

  1. 【绿盟大讲堂】哈希长度扩展攻击
  2. 【密码学】C 语言实现 SHA-1 填充和数据扩充
  3. 百度百科词条—SHA家族
  4. Understanding MD5 Length Extension Attack
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值