1.首先加上一些库:apt-get install openssl libssl-dev libssl-doc libcurl4-openssl-dev
2.实现一个用MD5加密密码的小程序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/hmac.h>
#include<openssl/md5.h>
int
output(char *p,unsigned char* pwd, int len)
{
int i;
printf("%s",p);
for(i=0;i<len;i++)
{
printf("%x",pwd[i]);
}
printf("\n");
return 0;
}
int
main(int argc, char *argv[])
{
if(argc<2)
{
fprintf(stderr,"%s <original password><salt password><hash length>\n",argv[0]);
return 1;
}
int i,hashLen;
unsigned char *originalPwd;
unsigned char *saltPwd;
originalPwd = (unsigned char *)malloc(strlen(argv[1])+1);//argv[1]是初始密码
saltPwd = (unsigned char *)malloc(strlen(argv[2])+1); //argv[2]是加盐:是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符
strcpy(originalPwd,argv[1]);
strcpy(saltPwd,argv[2]);
hashLen = atoi(argv[3]); //设置加密密码的长度
unsigned char encryptPwd[hashLen];
printf("Before add salt into the original password:\n");
MD5((unsigned char *)originalPwd,strlen(originalPwd),encryptPwd);//使用MD5算法对密码进行加密(不加盐),并输出加密前后密码
output("Original Password = ",(unsigned char *)originalPwd,strlen(originalPwd));
output("Encrypt Password = ",(unsigned char *)encryptPwd,hashLen);
printf("\nAfter add salt into the original password:\n");
memset(encryptPwd,0,sizeof(encryptPwd));
strcat(originalPwd,saltPwd);
MD5((unsigned char *)originalPwd,strlen(originalPwd),encryptPwd);//使用MD5算法对密码进行加密(加盐),并输出加密前后密码
output("Original Password = ",(unsigned char *)originalPwd,strlen(originalPwd));
output("Encrypt Password = ",(unsigned char *)encryptPwd,hashLen);
return 0;
}
编译:
gcc md5test.c -o md5test -lcrypto
运行:
./md5test lebaishi wahaha 13
运行结果:
3.Java方法
假设我们想要对同一个字符串:"add and remove ip whitelist dynamically"进行MD5加密。
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5 {
public static void main(String[] args) throws NoSuchAlgorithmException{
String token = getMD5();
System.out.println("token = " + token);
}
static String getMD5() throws NoSuchAlgorithmException{
String plainText = "add and remove ip whitelist dynamically";
MessageDigest md5 = MessageDigest.getInstance("md5");
byte[] cipherData = md5.digest(plainText.getBytes());
StringBuilder builder = new StringBuilder();
for(byte cipher : cipherData) {
String toHexStr = Integer.toHexString(cipher & 0xff);
builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);
}
//System.out.println(builder.toString());
return builder.toString();
}
}
结果:token = 490c4ac2f07fdf3c3699536c398f8404
4.Python方式
4.1 对字符串计算md5:
import hashlib
m = hashlib.md5()
str = "add and remove ip whitelist dynamically"
m.update(str)
print m.hexdigest()
结果:490c4ac2f07fdf3c3699536c398f8404
4.2 对文件计算md5:
#!/usr/bin/env python
import hashlib,os,sys
def getFileMD5(filepath):
if os.path.isfile(filepath):
f = open(filepath,'rb')
md5obj = hashlib.md5()
md5obj.update(f.read())
hash = md5obj.hexdigest()
f.close()
return str(hash).lower()
return None
current_path = os.path.dirname(os.path.realpath(__file__))
file_name = current_path + os.path.sep + "file1"
print getFileMD5(file_name)
使用以上代码来计算超大文件(大于5GB)的话会出现内存被撑爆的错误:MemoryError,因此需要换一种方式来计算大文件的md5值:
def getMD5(self,filename):
md5_value = hashlib.md5()
with open(filename,"rb") as file:
while True:
data = file.read(2048)
if data == "":
break
md5_value.update(data)
return md5_value.hexdigest()
5.Shell方式
5.1 对字符串计算md5:
`echo -n "add and remove ip whitelist dynamically" | md5sum`
一条命令即可。
5.2 对文件计算md5:
md5sum file1 | awk '{print $1}'
可见:Linux md5和java md5以及python md5对统一字符串加密结果完全一致的。
6.Golang方式:
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
)
func calc1(path string) string {
file, err := os.Open(path)
md5hash := md5.New()
if err == nil {
io.Copy(md5hash, file)
}
return hex.EncodeToString(md5hash.Sum(nil))
}
func calc2(path string) string {
file, err := os.Open(path)
buf, _ := ioutil.ReadAll(file)//将文件转换成为[]byte
md5hash := md5.New()
if err == nil {
md5hash.Write(buf)
}
return hex.EncodeToString(md5hash.Sum(nil))
}
func main() {
path := "input.file"
res1 := calc1(path)
res2 := calc2(path)
fmt.Println(res1, res2)
}