当前位置: 首页 > 编程日记 > 正文

java加密算法

java加密算法


本篇内容简要介绍BASE64、MD5、SHA、HMAC几种加密算法。 
    BASE64编码算法不算是真正的加密算法。 
    MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。 

BASE64 
按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.) 
常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE64加密的。

主要就是BASE64Encoder、BASE64Decoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是8的倍数,如果不够位数以=符号填充。 

sun不推荐使用它们自己的base64,所以用apache的挺好!

MD5 
MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文件是否一致的。

通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串。

SHA 
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了,但是SHA仍然是公认的安全加密算法,较之MD5更为安全。

HMAC 
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。 

 BASE64的加密解密是双向的,可以求反解。 
    MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。
   单向加密的用途主要是为了校验数据在传输过程中是否被修改。

java代码

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;public class MyEncrypt {
public static final String KEY_SHA = "SHA";
public static final String KEY_MD5 = "MD5";
public static final String KEY_MAC = "HmacMD5";// sun不推荐使用它们自己的base64,用apache的挺好
/**
* BASE64解密
*/
public static byte[] decryptBASE64(byte[] dest) {
if (dest == null) {
return null;
}
return Base64.decodeBase64(dest);
}/**
* BASE64加密
*/
public static byte[] encryptBASE64(byte[] origin) {
if (origin == null) {
return null;
}
return Base64.encodeBase64(origin);
}/**
* MD5加密
* 
* @throws NoSuchAlgorithmException
*/
public static byte[] encryptMD5(byte[] data)
throws NoSuchAlgorithmException {
if (data == null) {
return null;
}
MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data);
return md5.digest();
}/**
* SHA加密
* 
* @throws NoSuchAlgorithmException
*/
public static byte[] encryptSHA(byte[] data)
throws NoSuchAlgorithmException {
if (data == null) {
return null;
}
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data);
return sha.digest();
}/**
* 初始化HMAC密钥
* 
* @throws NoSuchAlgorithmException
*/
public static String initMacKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
SecretKey secretKey = keyGenerator.generateKey();
return new String(encryptBASE64(secretKey.getEncoded()));
}/**
* HMAC加密
* 
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static byte[] encryptHMAC(byte[] data, String key)
throws NoSuchAlgorithmException, InvalidKeyException {
SecretKey secretKey = new SecretKeySpec(decryptBASE64(key.getBytes()),
KEY_MAC);
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
return mac.doFinal(data);}public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
String data = "简单加密";
System.out.println(new BigInteger(encryptBASE64(data.getBytes())).toString(16));
System.out.println(new BigInteger(encryptBASE64(data.getBytes())).toString(32));
System.out.println(new String(decryptBASE64(encryptBASE64(data.getBytes()))));System.out.println(new BigInteger(encryptMD5(data.getBytes())).toString());
System.out.println(new BigInteger(encryptSHA(data.getBytes())).toString());System.out.println(new BigInteger(encryptHMAC(data.getBytes(), initMacKey())).toString());
}}

可变MD5加密(Java实现)

可变在这里含义很简单,就是最终的加密结果是可变的,而非必需按标准MD5加密实现。Java类库security中的MessageDigest类就提供了MD5加密的支持,实现起来非常方便。为了实现更多效果,我们可以如下设计MD5工具类。

import java.security.MessageDigest;/*** 标准MD5加密方法,使用java类库的security包的MessageDigest类处理*/
public class MD5 {/*** 获得MD5加密密码的方法*/public static String getMD5ofStr(String origString) {String origMD5 = null;try {MessageDigest md5 = MessageDigest.getInstance("MD5");// md5.update(origString.getBytes());byte[] result = md5.digest(origString.getBytes());origMD5 = byteArray2HexStr(result);// if ("123".equals(origString)) {// System.out.println(new String(result));// System.out.println(new BigInteger(result).toString(16));// }} catch (Exception e) {e.printStackTrace();}return origMD5;}/*** 处理字节数组得到MD5密码的方法*/private static String byteArray2HexStr(byte[] bs) {StringBuffer sb = new StringBuffer();for (byte b : bs) {sb.append(byte2HexStr(b));}return sb.toString();}/*** 字节标准移位转十六进制方法*/private static String byte2HexStr(byte b) {String hexStr = null;int n = b;if (n < 0) {// 若需要自定义加密,请修改这个移位算法即可n = b & 0x7F + 128;}hexStr = Integer.toHexString(n / 16) + Integer.toHexString(n % 16);return hexStr.toUpperCase();}/*** 提供一个MD5多次加密方法*/public static String getMD5ofStr(String origString, int times) {String md5 = getMD5ofStr(origString);for (int i = 0; i < times - 1; i++) {md5 = getMD5ofStr(md5);}return getMD5ofStr(md5);}/*** 密码验证方法*/public static boolean verifyPassword(String inputStr, String MD5Code) {return getMD5ofStr(inputStr).equals(MD5Code);}/*** 重载一个多次加密时的密码验证方法*/public static boolean verifyPassword(String inputStr, String MD5Code,int times) {return getMD5ofStr(inputStr, times).equals(MD5Code);}/*** 提供一个测试的主函数*/public static void main(String[] args) {System.out.println("123:" + getMD5ofStr("123"));System.out.println("123456789:" + getMD5ofStr("123456789"));System.out.println("sarin:" + getMD5ofStr("sarin"));System.out.println("123:" + getMD5ofStr("123", 4));}
}

可以看出实现的过程非常简单,因为由java类库提供了处理支持。但是要清楚的是这种方式产生的密码不是标准的MD5码,它需要进行移位处理才能得到标准MD5码。这个程序的关键之处也在这了,怎么可变?调整移位算法不就可变了么!不进行移位,也能够得到32位的密码,这就不是标准加密了,只要加密和验证过程使用相同的算法就可以了。 
    MD5加密还是很安全的,像CMD5那些穷举破解的只是针对标准MD5加密的结果进行的,如果自定义移位算法后,它还有效么?可以说是无解的了,所以MD5非常安全可靠。 
    为了更可变,还提供了多次加密的方法,可以在MD5基础之上继续MD5,就是对32位的第一次加密结果再MD5,恩,这样去破解?没有任何意义。 
    这样在MIS系统中使用,安全可靠,欢迎交流,希望对使用者有用。 
    我们最后看看由MD5加密算法实现的类,那是非常庞大的。 

import java.lang.reflect.*;  /** * ********************************************** * md5 类实现了RSA Data Security, Inc.在提交给IETF * 的RFC1321中的MD5 message-digest 算法。 * *********************************************** */  public class MD5 {  /* 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的, 这里把它们实现成为static final是表示了只读,切能在同一个进程空间内的多个 Instance间共享*/  static final int S11 = 7;  static final int S12 = 12;  static final int S13 = 17;  static final int S14 = 22;  static final int S21 = 5;  static final int S22 = 9;  static final int S23 = 14;  static final int S24 = 20;  static final int S31 = 4;  static final int S32 = 11;  static final int S33 = 16;  static final int S34 = 23;  static final int S41 = 6;  static final int S42 = 10;  static final int S43 = 15;  static final int S44 = 21;  static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0 };  /* 下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中 被定义到MD5_CTX结构中 */  private long[] state = new long[4]; // state (ABCD)  private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb first)  private byte[] buffer = new byte[64]; // input buffer  /* digestHexStr是MD5的唯一一个公共成员,是最新一次计算结果的 16进制ASCII表示. */  public String digestHexStr;  /* digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值. */  private byte[] digest = new byte[16];  /* getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的. */  public String getMD5ofStr(String inbuf) {  md5Init();  md5Update(inbuf.getBytes(), inbuf.length());  md5Final();  digestHexStr = "";  for (int i = 0; i < 16; i++) {  digestHexStr += byteHEX(digest[i]);  }  return digestHexStr;  }  // 这是MD5这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数  public MD5() {  md5Init();  return;  }  /* md5Init是一个初始化函数,初始化核心变量,装入标准的幻数 */  private void md5Init() {  count[0] = 0L;  count[1] = 0L;  ///* Load magic initialization constants.  state[0] = 0x67452301L;  state[1] = 0xefcdab89L;  state[2] = 0x98badcfeL;  state[3] = 0x10325476L;  return;  }  /* F, G, H ,I 是4个基本的MD5函数,在原始的MD5的C实现中,由于它们是  简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们  实现成了private方法,名字保持了原来C中的。 */  private long F(long x, long y, long z) {  return (x & y) | ((~x) & z);  }  private long G(long x, long y, long z) {  return (x & z) | (y & (~z));  }  private long H(long x, long y, long z) {  return x ^ y ^ z;  }  private long I(long x, long y, long z) {  return y ^ (x | (~z));  }  /* FF,GG,HH和II将调用F,G,H,I进行近一步变换 FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */  private long FF(long a, long b, long c, long d, long x, long s, long ac) {  a += F(b, c, d) + x + ac;  a = ((int) a << s) | ((int) a >>> (32 - s));  a += b;  return a;  }  private long GG(long a, long b, long c, long d, long x, long s, long ac) {  a += G(b, c, d) + x + ac;  a = ((int) a << s) | ((int) a >>> (32 - s));  a += b;  return a;  }  private long HH(long a, long b, long c, long d, long x, long s, long ac) {  a += H(b, c, d) + x + ac;  a = ((int) a << s) | ((int) a >>> (32 - s));  a += b;  return a;  }  private long II(long a, long b, long c, long d, long x, long s, long ac) {  a += I(b, c, d) + x + ac;  a = ((int) a << s) | ((int) a >>> (32 - s));  a += b;  return a;  }  /* md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的 */  private void md5Update(byte[] inbuf, int inputLen) {  int i, index, partLen;  byte[] block = new byte[64];  index = (int) (count[0] >>> 3) & 0x3F;  // /* Update number of bits */  if ((count[0] += (inputLen << 3)) < (inputLen << 3))  count[1]++;  count[1] += (inputLen >>> 29);  partLen = 64 - index;  // Transform as many times as possible.  if (inputLen >= partLen) {  md5Memcpy(buffer, inbuf, index, 0, partLen);  md5Transform(buffer);  for (i = partLen; i + 63 < inputLen; i += 64) {  md5Memcpy(block, inbuf, 0, i, 64);  md5Transform(block);  }  index = 0;  } else  i = 0;  ///* Buffer remaining input */  md5Memcpy(buffer, inbuf, index, i, inputLen - i);  }  /* md5Final整理和填写输出结果 */  private void md5Final() {  byte[] bits = new byte[8];  int index, padLen;  ///* Save number of bits */  Encode(bits, count, 8);  ///* Pad out to 56 mod 64.  index = (int) (count[0] >>> 3) & 0x3f;  padLen = (index < 56) ? (56 - index) : (120 - index);  md5Update(PADDING, padLen);  ///* Append length (before padding) */  md5Update(bits, 8);  ///* Store state in digest */  Encode(digest, state, 16);  }  /* md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的 字节拷贝到output的outpos位置开始 */  private void md5Memcpy(byte[] output, byte[] input, int outpos, int inpos, int len) {  int i;  for (i = 0; i < len; i++)  output[outpos + i] = input[inpos + i];  }  /* md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节 */  private void md5Transform(byte block[]) {  long a = state[0], b = state[1], c = state[2], d = state[3];  long[] x = new long[16];  Decode(x, block, 64);  /* Round 1 */  a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */  d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */  c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */  b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */  a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */  d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */  c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */  b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */  a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */  d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */  c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */  b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */  a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */  d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */  c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */  b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */  /* Round 2 */  a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */  d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */  c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */  b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */  a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */  d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */  c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */  b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */  a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */  d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */  c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */  b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */  a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */  d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */  c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */  b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */  /* Round 3 */  a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */  d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */  c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */  b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */  a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */  d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */  c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */  b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */  a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */  d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */  c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */  b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */  a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */  d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */  c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */  b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */  /* Round 4 */  a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */  d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */  c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */  b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */  a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */  d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */  c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */  b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */  a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */  d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */  c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */  b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */  a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */  d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */  c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */  b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */  state[0] += a;  state[1] += b;  state[2] += c;  state[3] += d;  }  /*Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的, 只拆低32bit,以适应原始C实现的用途 */  private void Encode(byte[] output, long[] input, int len) {  int i, j;  for (i = 0, j = 0; j < len; i++, j += 4) {  output[j] = (byte) (input[i] & 0xffL);  output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);  output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);  output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);  }  }  /*Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的, 只合成低32bit,高32bit清零,以适应原始C实现的用途 */  private void Decode(long[] output, byte[] input, int len) {  int i, j;  for (i = 0, j = 0; j < len; i++, j += 4)  output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8) | (b2iu(input[j + 2]) << 16)  | (b2iu(input[j + 3]) << 24);  return;  }  /* b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算 */  public static long b2iu(byte b) {  return b < 0 ? b & 0x7F + 128 : b;  }  /*byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示, 因为java中的byte的toString无法实现这一点,我们又没有C语言中的 sprintf(outbuf,"%02X",ib) */  public static String byteHEX(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;  }  public static void main(String args[]) {  MD5 m = new MD5();  if (Array.getLength(args) == 0) { //如果没有参数,执行标准的Test Suite  System.out.println("MD5 Test suite:");  System.out.println("MD5(\"\"):" + m.getMD5ofStr(""));  System.out.println("MD5(\"a\"):" + m.getMD5ofStr("a"));  System.out.println("MD5(\"abc\"):" + m.getMD5ofStr("abc"));  System.out.println("MD5(\"11\"):" + m.getMD5ofStr("11"));  System.out.println("MD5(\"123\"):" + m.getMD5ofStr("123"));  System.out.println("MD5(\"message digest\"):" + m.getMD5ofStr("message digest"));  System.out.println("MD5(\"abcdefghijklmnopqrstuvwxyz\"):" + m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz"));  System.out.println("MD5(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"):"  + m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));  } else  System.out.println("MD5(" + args[0] + ")=" + m.getMD5ofStr(args[0]));  }  }  





相关文章:

在多台FMS服务器之间共享流

FMS有一个非常重要的功能,那就是可以在多台服务器之间共享流. 利用这一功能,我们可以把源服务器上的流分发到其它的服务器,这些获得流的服务器同样可以作为新的源服务器使用.这个功能有点象FMS集群. 我们都知道,利用WMP插件可以获取网上的流媒体地址制作网络电视台,其实利用Fla…

linux实现nat转发和内部端口映射

路由机 eth0:114.114.114.114(公网ip) eth1:192.168.1.1(内网ip) pc1 eth0:192.168.1.2(内网ip) eth1(拨号ip) pc2 eth0:192.168.1.3(内网ip) eth1(拨号ip) 1.配置路由机网卡信息 vim /etc/sysconfig/network-scripts/ifcfg-eth1 TYPEEthernet BOOTPROTOstati…

15级团队学习成果汇报 -- 利用C#语言实现展览厅

本图文主要是15级团队学习成果的汇报“ 利用C#语言实现展览厅”。

我所理解的Spring AOP的基本概念

Spring AOP中的概念晦涩难懂&#xff0c;读官方文档更是像读天书&#xff0c;看了很多例子后&#xff0c;写一些自己理解的一些spring的概念。要理解面向切面编程&#xff0c;要首先理解代理模式和动态代理模式。 假设一个OA系统中的一个功能是查看考勤信息&#xff0c;那么我…

你需要的大概不是 enumerated

作者&#xff1a;KHANLOU&#xff0c;原文链接&#xff0c;原文日期&#xff1a;2017-03-28译者&#xff1a;四娘&#xff1b;校对&#xff1a;Cwift&#xff1b;定稿&#xff1a;CMBSwift 标准库里最容易被滥用的就是 Sequence 的 enumerated() 函数。这个函数会返回一个新的序…

Matlab与线性代数 -- 正态分布的随机矩阵

本图文介绍了如何利用Matlab实现正态分布的随机矩阵。

修改maven本地仓库的位置及疑惑

maven的默认仓库在~/.m2/repository下&#xff0c;这个是在c盘下&#xff0c;很多系统程序都在c盘&#xff0c;而且c盘的空间有时候不够大&#xff0c;所以经常要修改本地repository的位置&#xff0c;我做的修改如下&#xff1a; 在D盘建立一个repository&#xff1a;D:\mave…

值得FS去的英雄副本

1) 奥金尼地穴腰带 18耐23智19精 22法爆28法伤2) 塞泰克大厅法杖 40耐42智 37法爆168法伤3) 暗影迷宫腰带 31耐27智 17法爆34法伤4) 奴隶围栏饰品 37法伤一定几率使施法加速320,持续6秒5) 盘牙洞穴魔杖 10智 11法爆20法伤转载于:https://www.cnblogs.com/Evanescence/archive/2…

利用C#语言实现小闹钟

本图文主要是15级团队学习成果的汇报“ 利用C#语言实现小闹钟”。

Windows和linux双系统——改动默认启动顺序

电脑上装了Windows 7和Ubantu双系统&#xff0c;因为Linux系统用的次数比較少而且还是默认的启动项对此非常不能容忍&#xff0c;因此得改动Windows为默认的启动项。 因为电脑上的系统引导程序是GRUB&#xff0c;因此改动当然也就落到Linux系统上啦。改动/boot/grub/grub.cfg该…

ThreadLocal的使用方法

ThreadLocal的含义是Thread Local Variable&#xff0c;它可以声明一个字段&#xff0c;使得不同的线程访问这个字段时&#xff0c;获取的都是不同的副本&#xff0c;互不影响。 ThreadLocal的作用和在每个Thread类声明一个字段相同&#xff0c;那么什么时候使用它呢&#xff1…

如何实现对象交互

在本篇随笔中&#xff0c;我们学习下什么是对象选择&#xff0c;投影和反投影是如何工作的&#xff0c;怎样使用Three.js构建可使用鼠标和对象交互的应用。例如当鼠标移到对象&#xff0c;对象变成红色&#xff0c;鼠标移走&#xff0c;对象又恢复原来的颜色。 本篇随笔的源代码…

Matlab与线性代数 -- 矩阵的大小

本图文介绍了如何利用Matlab求矩阵的大小。

最近做了一个小小的系统,收获挺大的....我想总结一下

首先我要感谢老许,是他给了我这次机会.以后我会把我的经验一点一点总结出来....为那些在编程之路上的迷茫者找到方向活着让人兴奋...总觉的应该去做点什么做工程开发吧----我的老师阿温说过一句话让我记忆尤新:"坚持成就传奇".我想用他去勉力每一个在人生路上奋斗的人…

Hibernate和iBATIS 优缺点比较

选择Hibernate还是iBATIS都有它的道理&#xff1a;Hibernate的特点&#xff1a;Hibernate功能强大&#xff0c;数据库无关性好&#xff0c;O/R映射能力强&#xff0c;如果你对Hibernate相当精通&#xff0c;而且对Hibernate进行了适当的封装&#xff0c;那么你的项目整个持久层…

Matlab与线性代数 -- 矩阵的秩

本图文详细介绍了利用Matlab求矩阵秩的方法。

iOS开发 最近开发了蓝牙模块,在此记录总结一下

为什么80%的码农都做不了架构师&#xff1f;>>> 1.基本概念 <1>中心者模式&#xff1a;常用的&#xff08;其实99.99%&#xff09;就是使用中心者模式作为开发&#xff0c;就是我们手机作为主机&#xff0c;连接蓝牙外设。由于开发只用到了中心者模式&#x…

asp.net实现在网页上自动显示超链接以及Email地址

人们总喜欢在帖子中加上各种有用的URL链接或Email地址。而笔者当初设计时没有考虑到这一点&#xff0c;使得这些URL链接或Email地址只能以文字的形式而并不是以超链接的形式显示&#xff0c;其它浏览帖子的人还必须把这些URL链接拷贝到浏览器中或把Email地址拷贝到Outlook中才能…

用开放地址法中的线性探查法解决冲突实现哈希表的运算

为了更深的理解哈希算法&#xff0c;自己写了用开放地址法中的线性探查法解决冲突实现哈希表的运算。 /*** Created by lirui on 14-8-13.* 用开放地址法中的线性探查法解决冲突实现哈希表的运算。*/ public class MyHashSearch {public static final int SIZE 10;public sta…

Re: 求助:5道算法题

http://www.newsmth.net/frames.html发信人: cutepig (cutepig), 信区: Algorithm标 题: 求助&#xff1a;5道算法题发信站: 水木社区 (Sat Nov 10 18:25:06 2007), 站内1)given a integer, output its previous and next neighbor number which has the same number of bit 1…

Linux下des对称性加密

最近对接公安审计一些经历 对方的需求&#xff1a; 打成zip包对zip包进行des-cbc对称性加密&#xff0c;使用约定好的 -K和-iv值比如 -K "abcd$#!" -iv "efgh$#!"加密后做base64编码起初是想尝试用 php 去做&#xff0c;经过一阵折腾之后发现&#xff0c;p…

在软件中常用的“撤销”操作,其本质是“栈”!

本文介绍了栈的定义与操作并利用顺序表和链表实现了栈这种常用的数据结构。

用拉链法实现哈希算法的运算

package lirui.find;import java.util.LinkedList;/*** Created by lirui on 14-8-13.* 用拉链法实现哈希算法的运算*/ public class MyHashSearch2 {public static final int SIZE 10;public static MyHashElement[] hashtable new MyHashElement[SIZE];// 记录hash表中的数…

C#图片处理常见方法性能比较

在.NET编程中&#xff0c;由于GDI的出现&#xff0c;使得对于图像的处理功能大大增强。在文通过一个简单黑白处理实例介绍在.NET中常见的图片处理方法和原理并比较各种方法的性能。 黑白处理原理&#xff1a;彩色图像处理成黑白效果通常有3种算法&#xff1b; (1).最大值法: 使…

软件中常用的“发送邮件”、“打印文档”,其本质是“队列”!

本图文详细介绍了顺序队列、循环队列、链队列的实现过程。

二分查找的循环实现和递归实现

自己实现了二分查找的循环实现和递归实现 说明&#xff1a;二分查找适用于顺序存储结构&#xff0c;不适于链式存储结构&#xff0c;是一个高效的查找方法。虽然折半查找效率高&#xff0c;但是要排序&#xff0c;排序本身是一种很费时的运算。要求传入的表是有序的。二分查找的…

CentOS6.8 编译安装LNMP

思路&#xff1a;根据Linux系统以及公司网站系统的信息&#xff0c;选择合适的安装包进行安装 一、查看系统信息 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # grep MemTotal /proc/meminfo # 查看内…

js入门·循环与判断/利用函数的简单实例/使用对象/列举对象属性的名称

1,列举对象属性的名称<script language"javascript">varobjnewObject();obj.a"您好&#xff0c;我是田洪川";obj.b"你是田洪川咋的&#xff0c;不得了啊&#xff1f;";obj.c"西西&#xff0c;哈哈&#xff0c;我是属性 c ";//上…

Matlab与数据结构 -- 对向量的排序

本图文介绍了Matlab怎样实现对向量的排序。

HashMap和HashSet原理及底层实现

HashMap底层用哈希算法实现&#xff0c;下面看一下哈希算表的整体概括&#xff1a; 当map.put(“key”,”values”);的时候&#xff0c;底层是这样的&#xff1a; static final Entry<?,?>[] EMPTY_TABLE {}; transient Entry<K,V>[] table (Entry<K,V&g…