`
Huaqingfly
  • 浏览: 57065 次
社区版块
存档分类
最新评论

SHA-1摘要算法源码

阅读更多
public class SHA1 {
    private final int[] abcde = {
            0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
        };

    // 摘要数据存储数组
    private int[] digestInt = new int[5];

    // 计算过程中的临时数据存储数组
    private int[] tmpData = new int[80];

    // 计算sha-1摘要
    private int process_input_bytes(byte[] bytedata) {
        // 初试化常量
        System.arraycopy(abcde, 0, digestInt, 0, abcde.length);

        // 格式化输入字节数组,补10及长度数据
        byte[] newbyte = byteArrayFormatData(bytedata);

        // 获取数据摘要计算的数据单元个数
        int MCount = newbyte.length / 64;

        // 循环对每个数据单元进行摘要计算
        for (int pos = 0; pos < MCount; pos++) {
            // 将每个单元的数据转换成16个整型数据,并保存到tmpData的前16个数组元素中
            for (int j = 0; j < 16; j++) {
                tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4));
            }

            // 摘要计算函数
            encrypt();
        }

        return 20;
    }

    // 格式化输入字节数组格式
    private byte[] byteArrayFormatData(byte[] bytedata) {
        // 补0数量
        int zeros = 0;

        // 补位后总位数
        int size = 0;

        // 原始数据长度
        int n = bytedata.length;

        // 模64后的剩余位数
        int m = n % 64;

        // 计算添加0的个数以及添加10后的总长度
        if (m < 56) {
            zeros = 55 - m;
            size = n - m + 64;
        } else if (m == 56) {
            zeros = 63;
            size = n + 8 + 64;
        } else {
            zeros = 63 - m + 56;
            size = (n + 64) - m + 64;
        }

        // 补位后生成的新数组内容
        byte[] newbyte = new byte[size];
        // 复制数组的前面部分
        System.arraycopy(bytedata, 0, newbyte, 0, n);

        // 获得数组Append数据元素的位置
        int l = n;
        // 补1操作
        newbyte[l++] = (byte) 0x80;

        // 补0操作
        for (int i = 0; i < zeros; i++) {
            newbyte[l++] = (byte) 0x00;
        }

        // 计算数据长度,补数据长度位共8字节,长整型
        long N = (long) n * 8;
        byte h8 = (byte) (N & 0xFF);
        byte h7 = (byte) ((N >> & 0xFF);
        byte h6 = (byte) ((N >> 16) & 0xFF);
        byte h5 = (byte) ((N >> 24) & 0xFF);
        byte h4 = (byte) ((N >> 32) & 0xFF);
        byte h3 = (byte) ((N >> 40) & 0xFF);
        byte h2 = (byte) ((N >> 48) & 0xFF);
        byte h1 = (byte) (N >> 56);
        newbyte[l++] = h1;
        newbyte[l++] = h2;
        newbyte[l++] = h3;
        newbyte[l++] = h4;
        newbyte[l++] = h5;
        newbyte[l++] = h6;
        newbyte[l++] = h7;
        newbyte[l++] = h8;

        return newbyte;
    }

    private int f1(int x, int y, int z) {
        return (x & y) | (~x & z);
    }

    private int f2(int x, int y, int z) {
        return x ^ y ^ z;
    }

    private int f3(int x, int y, int z) {
        return (x & y) | (x & z) | (y & z);
    }

    private int f4(int x, int y) {
        return (x << y) | x >>> (32 - y);
    }

    // 单元摘要计算函数
    private void encrypt() {
        for (int i = 16; i <= 79; i++) {
            tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^
                    tmpData[i - 16], 1);
        }

        int[] tmpabcde = new int[5];

        for (int i1 = 0; i1 < tmpabcde.length; i1++) {
            tmpabcde[i1] = digestInt[i1];
        }

        for (int j = 0; j <= 19; j++) {
            int tmp = f4(tmpabcde[0], 5) +
                f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
                tmpData[j] + 0x5a827999;
            tmpabcde[4] = tmpabcde[3];
            tmpabcde[3] = tmpabcde[2];
            tmpabcde[2] = f4(tmpabcde[1], 30);
            tmpabcde[1] = tmpabcde[0];
            tmpabcde[0] = tmp;
        }

        for (int k = 20; k <= 39; k++) {
            int tmp = f4(tmpabcde[0], 5) +
                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
                tmpData[k] + 0x6ed9eba1;
            tmpabcde[4] = tmpabcde[3];
            tmpabcde[3] = tmpabcde[2];
            tmpabcde[2] = f4(tmpabcde[1], 30);
            tmpabcde[1] = tmpabcde[0];
            tmpabcde[0] = tmp;
        }

        for (int l = 40; l <= 59; l++) {
            int tmp = f4(tmpabcde[0], 5) +
                f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
                tmpData[l] + 0x8f1bbcdc;
            tmpabcde[4] = tmpabcde[3];
            tmpabcde[3] = tmpabcde[2];
            tmpabcde[2] = f4(tmpabcde[1], 30);
            tmpabcde[1] = tmpabcde[0];
            tmpabcde[0] = tmp;
        }

        for (int m = 60; m <= 79; m++) {
            int tmp = f4(tmpabcde[0], 5) +
                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
                tmpData[m] + 0xca62c1d6;
            tmpabcde[4] = tmpabcde[3];
            tmpabcde[3] = tmpabcde[2];
            tmpabcde[2] = f4(tmpabcde[1], 30);
            tmpabcde[1] = tmpabcde[0];
            tmpabcde[0] = tmp;
        }

        for (int i2 = 0; i2 < tmpabcde.length; i2++) {
            digestInt[i2] = digestInt[i2] + tmpabcde[i2];
        }

        for (int n = 0; n < tmpData.length; n++) {
            tmpData[n] = 0;
        }
    }

    // 4字节数组转换为整数
    private int byteArrayToInt(byte[] bytedata, int i) {
        return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) |
        ((bytedata[i + 2] & 0xff) << | (bytedata[i + 3] & 0xff);
    }

    // 整数转换为4字节数组
    private void intToByteArray(int intValue, byte[] byteData, int i) {
        byteData[i] = (byte) (intValue >>> 24);
        byteData[i + 1] = (byte) (intValue >>> 16);
        byteData[i + 2] = (byte) (intValue >>>;
        byteData[i + 3] = (byte) intValue;
    }

    // 将字节转换为十六进制字符串
    private static String byteToHexString(byte ib) {
        char[] Digit = {
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
                'D', 'E', 'F'
            };
        char[] ob = new char[2];
        ob[0] = Digit[(ib >>> 4) & 0X0F];
        ob[1] = Digit[ib & 0X0F];

        String s = new String(ob);

        return s;
    }

    // 将字节数组转换为十六进制字符串
    private static String byteArrayToHexString(byte[] bytearray) {
        String strDigest = "";

        for (int i = 0; i < bytearray.length; i++) {
            strDigest += byteToHexString(bytearray[i]);
        }

        return strDigest;
    }

    // 计算sha-1摘要,返回相应的字节数组
    public byte[] getDigestOfBytes(byte[] byteData) {
        process_input_bytes(byteData);

        byte[] digest = new byte[20];

        for (int i = 0; i < digestInt.length; i++) {
            intToByteArray(digestInt[i], digest, i * 4);
        }

        return digest;
    }

    // 计算sha-1摘要,返回相应的十六进制字符串
    public String getDigestOfString(byte[] byteData) {
        return byteArrayToHexString(getDigestOfBytes(byteData));
    }

    public static void main(String[] args) {
        String data = "1";
        System.out.println(data);

        String digest = new SHA1().getDigestOfString(data.getBytes());
        System.out.println(digest);
    }
}
分享到:
评论

相关推荐

    SHA-1密码哈希算法(c语言实现)

    SHA-1密码哈希算法是一种广泛应用于信息安全领域的散列函数,它将任意长度的数据转化为固定长度的摘要,常用于验证数据完整性或密码存储。本文将详细介绍SHA-1算法的原理和C语言实现,并分析给定的文件内容。 SHA-1...

    SHA-1算法源码(C++)

    SHA-1算法源码(C++),简单易懂,请查看!

    SHA-1算法源码(C++),简单易懂,请查看!

    SHA-1算法源码(C++),简单易懂,请查看!

    信息安全实验-MD5,SHA-1信息摘要计算(MFC)

    在实验中,你可能需要理解SHA-1的工作原理,并能用MFC编写代码来计算SHA-1摘要。 在实验中,你可能会遇到以下关键知识点: 1. **散列函数基础**:了解散列函数的基本概念,包括哈希碰撞、不可逆性以及其在信息安全...

    sha-1算法java实现【jar包+源码+文档】

    这个类提供了一种标准的方式来计算各种消息摘要,包括SHA-1。下面是一个简单的SHA-1散列计算示例: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class ...

    SHA-1.rar_MAC算法 C语言_SHA-1 MAC_mac_mac算法-sha_sha 1

    描述中提到的"C语言实现源码"表明这个压缩包包含的是用C编程语言编写的代码,用于实现SHA-1 MAC算法。C语言是一种底层、高效的编程语言,适用于编写系统级软件和加密算法这样的性能敏感代码。 在标签中,"mac算法...

    可直接运行SHA-1源码SHA-1.rar

    这个"SHA-1源码SHA-1.rar"压缩包文件包含了可直接运行的SHA-1算法实现,特别适合于那些想深入理解或在VC++6.0环境中实践该算法的开发者。VC++6.0是微软公司开发的一款经典且功能强大的C++集成开发环境,尽管现在已经...

    MD5-SHA1-SHA256算法C源码

    然而,自2005年起,已出现对SHA1的碰撞攻击,尽管实际应用中找到碰撞仍具有挑战性,但这也标志着SHA1逐渐被淘汰,被更安全的算法所替代。 SHA256是SHA-2家族的一员,由NIST(美国国家标准和技术研究所)在2001年...

    SHA-256算法的C++实现及demo

    1. **初始化哈希值**:SHA-256算法开始时会使用一组固定的初始化向量,这些向量是64位整数数组。 2. **分块处理**:输入数据被分成512位的数据块进行处理。每个数据块首先会被填充到512位,并附加一个表示原始输入...

    SHA-1加密算法源代码

    在VC++环境中实现SHA-1加密算法,你需要理解以下关键概念和步骤: 1. **哈希函数基础**:哈希函数是一种单向函数,它将任意长度的输入转化为固定长度的输出。这种转化过程使得原始输入无法通过哈希值轻易还原,从而...

    VC版SHA-1程序和源码

    总之,"VC版SHA-1程序和源码"是一个宝贵的学习资源,它不仅提供了SHA-1算法的实际应用示例,还为开发者提供了一个研究和学习哈希函数实现的平台。通过这个项目,你可以提升自己的C++编程技能,了解安全领域的重要...

    SHA-1实现源码VC工程已经测试程序,对比测试结果工具

    源码的编写目的是为了实现SHA-1算法,并且附带了测试程序,这有助于验证算法的正确性。 SHA-1算法的基本工作原理是将输入数据(也称为预映射消息)通过一系列的数学运算,包括位移、异或、加法等,转化为一个固定...

    SHA-3(keccak)之C/C++官方源码

    它采用了Keccak算法,由Guido Bertoni、Joan Daemen、Stefan Keccak团队在2007年设计,旨在解决SHA-1和SHA-2系列的安全性问题。Keccak算法的设计目标是提供更高的安全性和效率,以及抵御未来可能出现的攻击方法。 ...

    clojure-sha-3-源码.rar

    了解Clojure SHA-3的源码,不仅可以帮助我们深入理解SHA-3算法的工作原理,还能让我们更好地掌握Clojure编程语言的特性,以及如何在函数式编程环境中实现复杂的算法。同时,这对于进行安全性相关的开发,如数字签名...

    Delphi sha1加密源码

    Delphi SHA1加密源码是用于在Delphi编程环境中实现SHA1散列算法的代码,它确保了在不同编程语言(如C#、PHP)中进行加密时的一致性。SHA1(Secure Hash Algorithm 1)是一种广泛使用的密码学安全散列函数,由美国...

    MD4,MD5,SHA-1等加密算法的javascript 实现

    现在,SHA-1已经被建议替换为更安全的SHA-2或SHA-3家族算法。 在JavaScript中实现这些算法,开发者通常会使用现有的库,如crypto-js、js-sha1等。这些库提供了API接口,允许开发者轻松地计算输入字符串的MD4、MD5或...

    sha-1值计算工具+源码(基于WTL)

    1. **理解SHA-1算法**:首先,你需要了解SHA-1的基本工作原理,它包括几个内部变量,如中间消息摘要,以及一系列复杂的数学运算(如位旋转和异或)来更新这些变量。 2. **定义数据结构**:创建一个结构体来存储SHA-...

    SHA1算法C语言源代码

    SHA1算法在1995年发布,其全称为Secure Hash Algorithm 1,可以将任意长度的信息转化为固定长度的摘要值,通常为20字节(160位)。这个摘要具有单向性和抗碰撞性,即从摘要无法恢复原始数据,且不同的输入数据几乎不...

    sha1算法三_可直接在VS上运行_SHA1_SHA1算法源码_源码

    在VS中直接运行SHA1算法源码,首先需要确保源码文件(通常是`.c`或`.cpp`文件)已经正确导入项目,并且设置好编译器选项。VS提供了一个直观的IDE界面,可以在其中编写、编译和调试代码。源码通常会包含一个主函数,...

    sha256-512加密算法

    而`sha2`目录很可能是存放具体实现的源码文件,包括`sha256.cpp`和`sha512.cpp`,分别对应两种哈希函数的实现。这些源文件可能还包含了头文件,定义了函数接口,以及可能的测试用例。 总的来说,理解和实现SHA-256...

Global site tag (gtag.js) - Google Analytics