首页 > 请问下面java的Sha1加密在c#中对应要怎么写?

请问下面java的Sha1加密在c#中对应要怎么写?

 /**
 * 读取指定文件块数据Sha1
 *
 * @param fis
 * @return
 */
private static MessageDigest calSha1(BufferedInputStream fis) {
    MessageDigest sha1 = null;
    try {
        byte[] buffer = new byte[1024];
        int numRead = 0;
        int total = 0;
        sha1 = MessageDigest.getInstance("SHA-1");
        while ((numRead = fis.read(buffer)) > 0) {
            sha1.update(buffer, 0, numRead);
            total += numRead;
            if (total >= BLOCK_SIZE) {//每次最多读入4M
                break;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sha1;
}

   /**
 * 获取hash/etag,根据File文件计算hash值
 *
 * @param file 文件
 * @return
 */
public static String getEtagHash(File file) {
    String etagHash = null;
    BufferedInputStream fis = null;
    try {
        if (file.exists()) {
            byte[] ret = new byte[21];
            long blockCount = blockCount(file.length());
            fis = new BufferedInputStream(new FileInputStream(file));
            if (blockCount <= 1) { // 文件块数小于等于1块
                MessageDigest sha1 = calSha1(fis);
                if (null != sha1) {
                    byte[] input = sha1.digest();
                    ret[0] = BYTE_LOW_4;
                    for (int i = 0; i < 20; ++i) {//SHA1算法位20字节
                        ret[i + 1] = input[i];
                    }
                }
            } else {//将所有sha1值按切块顺序拼接
                byte[] rec = new byte[(int) blockCount * 20];
                ret[0] = BYTE_OVER_4;
                int i, cnt = 0;
                for (i = 0; i < blockCount; i++) {//每块文件分别计算sha1
                    MessageDigest sha1 = calSha1(fis);
                    if (null != sha1) {
                        byte[] tmp = sha1.digest();
                        for (int j = 0; j < 20; j++) {
                            rec[cnt++] = tmp[j];
                        }
                    }
                }
                MessageDigest sha1 = MessageDigest.getInstance("SHA-1");//对拼接好的数据再做sha1计算
                sha1.update(rec, 0, (int) blockCount * 20);
                byte[] tmp = sha1.digest();
                for (i = 0; i < 20; ++i) {//在最前面拼上单个字节,值为0x96
                    ret[i + 1] = tmp[i];
                }
            }
            etagHash = EncodeUtils.urlsafeEncodeString(ret);
        } else {
            System.out.println("File[" + file.getAbsolutePath() + "] Not Exist,Cannot Calculate Hash!");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (fis != null) {
                fis.close();
                fis = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return etagHash;
}

使用 System.Security.Cryptography.HashAlgorithm 抽象类创建 SHA1 实例,再调用其 ComputeHash 等方法计算 Hash

HashAlgorithm hash = HashAlgorithm.Create("SHA1");
byte[] code = hash.ComputeHash(Encoding.UTF8.GetBytes("abcdefg"));
Console.WriteLine(BitConverter.ToString(code));
// 2F-B5-E1-34-19-FC-89-24-68-65-E7-A3-24-F4-76-EC-62-4E-87-40

如果要算一个文件的 Hash,用 HashAlgorithm.ComputeHash(Stream),需要先用 System.IO.FileStream 把文件打开为 Stream

HashAlgorithm sha1 = HashAlgorithm.Create("sha1");
byte[] result;
using (FileStream fs = new FileStream(filename, FileMode.Open)) {
    result = sha1.ComputeHash(fs);
}
Console.WriteLine(BitConverter.ToString(result).Replace("-", string.Empty));

补充一下

数值和类型转换可以使用 Viyi.Util 中的扩展方法。

十六进制字符串和 byte] 之间可以参考 [ASCII编码解码:Base64和Hex

【热门文章】
【热门文章】