除空字符串

如何解决除空字符串

我正在尝试创建自己的哈希框架/库,但是偶然发现了一个问题。当我计算一个空字符串的SHA256哈希值时,该哈希值被成功计算,但是当我为其他内容计算时,它失败了。有人可以帮我找出原因吗?

Wikipedia提供,当在线执行并使用python时,此哈希匹配。

let h = SHA256(message: Data("".utf8))
let d = h.digest()
// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
print(d)

但是“ Hello world”不是

let h = SHA256(message: Data("Hello world".utf8))
let d = h.digest()
// ce9f4c08f0688d09b8061ed6692c1d5af2516c8682fad2d9a5d72f96ba787a80
print(d)
// Expected:
// 64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c

我希望有人能帮助我。下面的SHA256实现:

/*
 First 32 bits of the fractional parts of the
 square roots of the first 8 primes 2..19.
*/

fileprivate let kSHA256H0: UInt32 = 0x6a09e667
fileprivate let kSHA256H1: UInt32 = 0xbb67ae85
fileprivate let kSHA256H2: UInt32 = 0x3c6ef372
fileprivate let kSHA256H3: UInt32 = 0xa54ff53a
fileprivate let kSHA256H4: UInt32 = 0x510e527f
fileprivate let kSHA256H5: UInt32 = 0x9b05688c
fileprivate let kSHA256H6: UInt32 = 0x1f83d9ab
fileprivate let kSHA256H7: UInt32 = 0x5be0cd19

/*
 First 32 bits of the fractional parts of the
 cube roots of the first 64 primes 2..311.
 */

fileprivate let kSHA256K: [UInt32] = [
    0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
]

/// Shift the value of x n amount to the right.
/// - Parameters:
///   - x: The value to shift.
///   - n: The amount to shift by.
/// - Returns: The shifted value.
fileprivate func shiftRight(_ x: UInt32,_ n: UInt32) -> UInt32 { x >> n }

/// Rotate the value of x n amount of times.
/// - Parameters:
///   - x: The value to rotate.
///   - y: The amount to rotate by.
/// - Returns: The rotated value.
fileprivate func rotateRight(_ x: UInt32,_ y: UInt32) -> UInt32 { (x >> (y & 31)) | (x << (32 - (y & 31))) }

/// Split data into chunks of specified size.
/// - Note: This function will not pad or append data
/// to make sure all the chunks are equal in size.
/// - Parameters:
///   - data: The data to split.
///   - size: The size of a chunk.
/// - Returns: An array containing chunks of specified size (when able).
fileprivate func chunk(_ data: Data,toSize size: Int) -> [Data] {
    stride(from: 0,to: data.count,by: size).map {
        data.subdata(in: $0 ..< Swift.min($0 + size,data.count))
    }
}

public class SHA256 {
    
    /// The pre-processed data.
    fileprivate let message: Data
    
    fileprivate var hash = [
        kSHA256H0,kSHA256H1,kSHA256H2,kSHA256H3,kSHA256H4,kSHA256H5,kSHA256H6,kSHA256H7
    ]
    
    public init(message: Data) {
        self.message = Self.preProcess(message: message)
    }
    
    fileprivate static func preProcess(message: Data) -> Data {
        let L = message.count * 8   // Original message length in bits.
        var K = 0                   // Required padding bits.
        
        while (L + 1 + K + 64) % 512 != 0 {
            K += 1
        }
        
        var padding = Data(repeating: 0,count: K / 8)
        padding.insert(0x80,at: 0) // Insert 1000 0000 into the padding.
        
        var length = UInt64(L).bigEndian
        return message + padding + Data(bytes: &length,count: 8)
    }
    
    public func digest() -> Data {
        let chunks = chunk(message,toSize: 64)
        for chunk in chunks {
            var w = [UInt32](repeating: 0,count: 64)   // 64-entry message schedule array of 32-bit words.
            
            // Copy the chunk into first 16 words w[0..15] of the schedule array.
            for i in 0 ..< 16 {
                let sub = chunk.subdata(in: i ..< i + 4)
                w[i] = sub.withUnsafeBytes { $0.load(as: UInt32.self) }.bigEndian
            }
            
            // Extend the first 16 words into the remaining 48 words w[16..63] of the schedule array.
            for i in 16 ..< 64 {
                let s0 = rotateRight(w[i - 15],7) ^ rotateRight(w[i - 15],18) ^ shiftRight(w[i - 15],3)
                let s1 = rotateRight(w[i - 2],17) ^ rotateRight(w[i - 2],19) ^ shiftRight(w[i - 2],10)
                w[i] = s1 &+ w[i - 7] &+ s0 &+ w[i - 16]
            }
            
            // Create some working variables.
            var a = hash[0]
            var b = hash[1]
            var c = hash[2]
            var d = hash[3]
            var e = hash[4]
            var f = hash[5]
            var g = hash[6]
            var h = hash[7]
            
            // Compress function main loop.
            for i in 0 ..< 64 {
                let S1 = rotateRight(e,6) ^ rotateRight(e,11) ^ rotateRight(e,25)
                let ch = (e & f) ^ (~e & g)
                let T1 = h &+ S1 &+ ch &+ kSHA256K[i] &+ w[i]
                let S0 = rotateRight(a,2) ^ rotateRight(a,13) ^ rotateRight(a,22)
                let maj = (a & b) ^ (a & c) ^ (b & c)
                let T2 = S0 &+ maj
                
                h = g
                g = f
                f = e
                e = d &+ T1
                d = c
                c = b
                b = a
                a = T1 &+ T2
            }
            
            hash[0] &+= a
            hash[1] &+= b
            hash[2] &+= c
            hash[3] &+= d
            hash[4] &+= e
            hash[5] &+= f
            hash[6] &+= g
            hash[7] &+= h
        }
        
        return hash.map {
            var num = $0.bigEndian
            return Data(bytes: &num,count: 4)
        }.reduce(Data(),+)
    }

}

解决方法

结果是,我创建了错误的子数据以构造我的UInt32来创建消息调度数组。 (.digest()函数的前几行)

旧的是

let sub = chunk.subdata(in: i ..< i + 4)

新的是

let sub = chunk.subdata(in: i * 4 ..< (i * 4) + 4)

这解决了问题

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-