import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.io.*;
import java.math.BigInteger;
/**
* RSA 工具类。提供加密,解密,生成密钥对等方法。
* 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。
* @author xiaoyusong
* mail: [email protected]
* msn:[email protected]
* @since 2004-5-20
*
*/
public class RSAUtil {
/**
* 生成密钥对
* @return KeyPair
* @throws EncryptException
*/
public static KeyPair generateKeyPair() throws EncryptException {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
final int KEY_SIZE = 1024;//没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyPairGen.genKeyPair();
return keyPair;
} catch (Exception e) {
throw new EncryptException(e.getMessage());
}
}
/**
* 生成公钥
* @param molus
* @param publicExponent
* @return RSAPublicKey
* @throws EncryptException
*/
public static RSAPublicKey generateRSAPublicKey(byte[] molus, byte[] publicExponent) throws EncryptException {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new EncryptException(ex.getMessage());
}
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(molus), new BigInteger(publicExponent));
try {
return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
} catch (InvalidKeySpecException ex) {
throw new EncryptException(ex.getMessage());
}
}
/**
* 生成私钥
* @param molus
* @param privateExponent
* @return RSAPrivateKey
* @throws EncryptException
*/
public static RSAPrivateKey generateRSAPrivateKey(byte[] molus, byte[] privateExponent) throws EncryptException {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new EncryptException(ex.getMessage());
}
RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(molus), new BigInteger(privateExponent));
try {
return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
} catch (InvalidKeySpecException ex) {
throw new EncryptException(ex.getMessage());
}
}
/**
* 加密
* @param key 加密的密钥
* @param data 待加密的明文数据
* @return 加密后的数据
* @throws EncryptException
*/
public static byte[] encrypt(Key key, byte[] data) throws EncryptException {
try {
Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, key);
int blockSize = cipher.getBlockSize();//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;因此共有2个加密块,第一个127 byte第二个为1个byte
int outputSize = cipher.getOutputSize(data.length);//获得加密块加密后块大小
int leavedSize = data.length % blockSize;
int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
byte[] raw = new byte[outputSize * blocksSize];
int i = 0;
while (data.length - i * blockSize > 0) {
if (data.length - i * blockSize > blockSize)
cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
else
cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
//这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。
i++;
}
return raw;
} catch (Exception e) {
throw new EncryptException(e.getMessage());
}
}
/**
* 解密
* @param key 解密的密钥
* @param raw 已经加密的数据
* @return 解密后的明文
* @throws EncryptException
*/
public static byte[] decrypt(Key key, byte[] raw) throws EncryptException {
try {
Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE, key);
int blockSize = cipher.getBlockSize();
ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
int j = 0;
while (raw.length - j * blockSize > 0) {
bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
j++;
}
return bout.toByteArray();
} catch (Exception e) {
throw new EncryptException(e.getMessage());
}
}
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File file = new File("test.html");
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] tmpbuf = new byte[1024];
int count = 0;
while ((count = in.read(tmpbuf)) != -1) {
bout.write(tmpbuf, 0, count);
tmpbuf = new byte[1024];
}
in.close();
byte[] orgData = bout.toByteArray();
KeyPair keyPair = RSAUtil.generateKeyPair();
RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
byte[] pubModBytes = pubKey.getMolus().toByteArray();
byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
byte[] priModBytes = priKey.getMolus().toByteArray();
byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
RSAPublicKey recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
RSAPrivateKey recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
byte[] raw = RSAUtil.encrypt(priKey, orgData);
file = new File("encrypt_result.dat");
OutputStream out = new FileOutputStream(file);
out.write(raw);
out.close();
byte[] data = RSAUtil.decrypt(recoveryPubKey, raw);
file = new File("decrypt_result.html");
out = new FileOutputStream(file);
out.write(data);
out.flush();
out.close();
}
}
http://book.77169.org/data/web5409/20050328/20050328__3830259.html
这个行吧
http://soft.zdnet.com.cn/software_zone/2007/0925/523319.shtml
再参考这个吧
http://topic.csdn.net/t/20040427/20/3014655.html
② java十大算法
算法一:快速排序算法
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
算法步骤:
1 从数列中挑出一个元素,称为 "基准"(pivot),
2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
算法二:堆排序算法
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
堆排序的平均时间复杂度为Ο(nlogn) 。
算法步骤:
创建一个堆H[0..n-1]
把堆首(最大值)和堆尾互换
3. 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置
4. 重复步骤2,直到堆的尺寸为1
算法三:归并排序
归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
算法步骤:
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4. 重复步骤3直到某一指针达到序列尾
5. 将另一序列剩下的所有元素
③ 关于java新闻网站的算法
问:新闻网站,如新浪网站,比如说国际足球频道,每天会有跟新。请问这块在代码设计的地方,是从数据库中读取5条最新的(按照日期)还是说做一个程序由编辑强制置顶?
答:是从数据库中读取5条最新的(按照日期)
问:如果是论坛,需要把点击最高的新闻自动排到前面,这个怎么处理,需要用到servletcontext吗 ?
答:读取点击最高的新闻记录(你想读取几条就几条),然后放到网页上去,就怎么回事.......跟你平时放其他数据没什么区别,都是根据条件取数据而已.
④ 标签传播算法 可以用于计算信息传播的覆盖率吗
首先我们从氢氧化钠溶液增重2.2g入手,可以知道生成的二氧化碳的质量为2.2g。再根据CaCO3+2HCl==CaCl2+CO2↑+H2O,我们可以算出碳酸钙的质量为5g,也就是说碳酸钙的纯度是100%。那么碳酸钙的质量分数就是100%。2NaOH+CO2=Na2CO3+H2O,根据这条方程式可以算出氢氧化钠的质量为4g,那么质量分数就是4/100=4%希望能够帮到你!
⑤ 标签传播算法是一种分类算法,还是聚类算法
在聚类分析中,K-均值聚类算法(k-meansalgorithm)是无监督分类中的一种基本方法,其也称为C-均值算法,其基本思想是:通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果.\x0d假设要把样本集分为c个类别,算法如下:\x0d(1)适当选择c个类的初始中心;\x0d(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类,\x0d(3)利用均值等方法更新该类的中心值;\x0d(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代.\x0d下面介绍作者编写的一个分两类的程序,可以把其作为函数调用.\x0d%%function[samp1,samp2]=kmeans(samp);作为调用函数时去掉注释符\x0dsamp=[11.15066.72222.31395.901811.08275.745913.217413.82434.80050.937012.3576];%样本集\x0d[l0l]=size(samp);\x0d%%利用均值把样本分为两类,再将每类的均值作为聚类中心\x0dth0=mean(samp);n1=0;n2=0;c1=0.0;c1=double(c1);c2=c1;fori=1:lifsamp(i)<th0\x0dc1=c1+samp(i);n1=n1+1;elsec2=c2+samp(i);n2=n2+1;endendc1=c1/n1;c2=c2/n2;%初始聚类中心t=0;cl1=c1;cl2=c2;\x0dc11=c1;c22=c2;%聚类中心whilet==0samp1=zeros(1,l);\x0dsamp2=samp1;n1=1;n2=1;fori=1:lifabs(samp(i)-c11)<abs(samp(i)-c22)\x0dsamp1(n1)=samp(i);\x0dcl1=cl1+samp(i);n1=n1+1;\x0dc11=cl1/n1;elsesamp2(n2)=samp(i);\x0dcl2=cl2+samp(i);n2=n2+1;\x0dc22=cl2/n2;endendifc11==c1&&c22==c2t=1;endcl1=c11;cl2=c22;\x0dc1=c11;c2=c22;\x0dend%samp1,samp2为聚类的结果.\x0d初始中心值这里采用均值的法,也可以根据问题的性质,用经验的方法来确定,或者将样本集随机分成c类,计算每类的均值.\x0dk-均值算法需要事先知道分类的数量,这是其不足之处.
⑥ 如何用Java实现遗传算法
通过遗传算法走迷宫。虽然图1和图2均成功走出迷宫,但是图1比图2的路径长的多,且复杂,遗传算法可以计算出有多少种可能性,并选择其中最简洁的作为运算结果。
示例图1:
实现代码:
importjava.util.ArrayList;
importjava.util.Collections;
importjava.util.Iterator;
importjava.util.LinkedList;
importjava.util.List;
importjava.util.Random;
/**
* 用遗传算法走迷宫
*
* @author Orisun
*
*/
publicclassGA {
intgene_len;// 基因长度
intchrom_len;// 染色体长度
intpopulation;// 种群大小
doublecross_ratio;// 交叉率
doublemuta_ratio;// 变异率
intiter_limit;// 最多进化的代数
List<boolean[]> indivials;// 存储当代种群的染色体
Labyrinth labyrinth;
intwidth;//迷宫一行有多少个格子
intheight;//迷宫有多少行
publicclassBI {
doublefitness;
boolean[] indv;
publicBI(doublef,boolean[] ind) {
fitness = f;
indv = ind;
}
publicdoublegetFitness() {
returnfitness;
}
publicboolean[] getIndv() {
returnindv;
}
}
List<BI> best_indivial;// 存储每一代中最优秀的个体
publicGA(Labyrinth labyrinth) {
this.labyrinth=labyrinth;
this.width = labyrinth.map[0].length;
this.height = labyrinth.map.length;
chrom_len =4* (width+height);
gene_len =2;
population =20;
cross_ratio =0.83;
muta_ratio =0.002;
iter_limit =300;
indivials =newArrayList<boolean[]>(population);
best_indivial =newArrayList<BI>(iter_limit);
}
publicintgetWidth() {
returnwidth;
}
publicvoidsetWidth(intwidth) {
this.width = width;
}
publicdoublegetCross_ratio() {
returncross_ratio;
}
publicList<BI> getBest_indivial() {
returnbest_indivial;
}
publicLabyrinth getLabyrinth() {
returnlabyrinth;
}
publicvoidsetLabyrinth(Labyrinth labyrinth) {
this.labyrinth = labyrinth;
}
publicvoidsetChrom_len(intchrom_len) {
this.chrom_len = chrom_len;
}
publicvoidsetPopulation(intpopulation) {
this.population = population;
}
publicvoidsetCross_ratio(doublecross_ratio) {
this.cross_ratio = cross_ratio;
}
publicvoidsetMuta_ratio(doublemuta_ratio) {
this.muta_ratio = muta_ratio;
}
publicvoidsetIter_limit(intiter_limit) {
this.iter_limit = iter_limit;
}
// 初始化种群
publicvoidinitPopulation() {
Random r =newRandom(System.currentTimeMillis());
for(inti =0; i < population; i++) {
intlen = gene_len * chrom_len;
boolean[] ind =newboolean[len];
for(intj =0; j < len; j++)
ind[j] = r.nextBoolean();
indivials.add(ind);
}
}
// 交叉
publicvoidcross(boolean[] arr1,boolean[] arr2) {
Random r =newRandom(System.currentTimeMillis());
intlength = arr1.length;
intslice =0;
do{
slice = r.nextInt(length);
}while(slice ==0);
if(slice < length /2) {
for(inti =0; i < slice; i++) {
booleantmp = arr1[i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
}else{
for(inti = slice; i < length; i++) {
booleantmp = arr1[i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
}
}
// 变异
publicvoidmutation(boolean[] indivial) {
intlength = indivial.length;
Random r =newRandom(System.currentTimeMillis());
indivial[r.nextInt(length)] ^=false;
}
// 轮盘法选择下一代,并返回当代最高的适应度值
publicdoubleselection() {
boolean[][] next_generation =newboolean[population][];// 下一代
intlength = gene_len * chrom_len;
for(inti =0; i < population; i++)
next_generation[i] =newboolean[length];
double[] cumulation =newdouble[population];
intbest_index =0;
doublemax_fitness = getFitness(indivials.get(best_index));
cumulation[0] = max_fitness;
for(inti =1; i < population; i++) {
doublefit = getFitness(indivials.get(i));
cumulation[i] = cumulation[i -1] + fit;
// 寻找当代的最优个体
if(fit > max_fitness) {
best_index = i;
max_fitness = fit;
}
}
Random rand =newRandom(System.currentTimeMillis());
for(inti =0; i < population; i++)
next_generation[i] = indivials.get(findByHalf(cumulation,
rand.nextDouble() * cumulation[population -1]));
// 把当代的最优个体及其适应度放到best_indivial中
BI bi =newBI(max_fitness, indivials.get(best_index));
// printPath(indivials.get(best_index));
//System.out.println(max_fitness);
best_indivial.add(bi);
// 新一代作为当前代
for(inti =0; i < population; i++)
indivials.set(i, next_generation[i]);
returnmax_fitness;
}
// 折半查找
publicintfindByHalf(double[] arr,doublefind) {
if(find <0|| find ==0|| find > arr[arr.length -1])
return-1;
intmin =0;
intmax = arr.length -1;
intmedium = min;
do{
if(medium == (min + max) /2)
break;
medium = (min + max) /2;
if(arr[medium] < find)
min = medium;
elseif(arr[medium] > find)
max = medium;
else
returnmedium;
}while(min < max);
returnmax;
}
// 计算适应度
publicdoublegetFitness(boolean[] indivial) {
intlength = indivial.length;
// 记录当前的位置,入口点是(1,0)
intx =1;
inty =0;
// 根据染色体中基因的指导向前走
for(inti =0; i < length; i++) {
booleanb1 = indivial[i];
booleanb2 = indivial[++i];
// 00向左走
if(b1 ==false&& b2 ==false) {
if(x >0&& labyrinth.map[y][x -1] ==true) {
x--;
}
}
// 01向右走
elseif(b1 ==false&& b2 ==true) {
if(x +1< width && labyrinth.map[y][x +1] ==true) {
x++;
}
}
// 10向上走
elseif(b1 ==true&& b2 ==false) {
if(y >0&& labyrinth.map[y -1][x] ==true) {
y--;
}
}
// 11向下走
elseif(b1 ==true&& b2 ==true) {
if(y +1< height && labyrinth.map[y +1][x] ==true) {
y++;
}
}
}
intn = Math.abs(x - labyrinth.x_end) + Math.abs(y -labyrinth.y_end) +1;
// if(n==1)
// printPath(indivial);
return1.0/ n;
}
// 运行遗传算法
publicbooleanrun() {
// 初始化种群
initPopulation();
Random rand =newRandom(System.currentTimeMillis());
booleansuccess =false;
while(iter_limit-- >0) {
// 打乱种群的顺序
Collections.shuffle(indivials);
for(inti =0; i < population -1; i +=2) {
// 交叉
if(rand.nextDouble() < cross_ratio) {
cross(indivials.get(i), indivials.get(i +1));
}
// 变异
if(rand.nextDouble() < muta_ratio) {
mutation(indivials.get(i));
}
}
// 种群更替
if(selection() ==1) {
success =true;
break;
}
}
returnsuccess;
}
// public static void main(String[] args) {
// GA ga = new GA(8, 8);
// if (!ga.run()) {
// System.out.println("没有找到走出迷宫的路径.");
// } else {
// int gen = ga.best_indivial.size();
// boolean[] indivial = ga.best_indivial.get(gen - 1).indv;
// System.out.println(ga.getPath(indivial));
// }
// }
// 根据染色体打印走法
publicString getPath(boolean[] indivial) {
intlength = indivial.length;
intx =1;
inty =0;
LinkedList<String> stack=newLinkedList<String>();
for(inti =0; i < length; i++) {
booleanb1 = indivial[i];
booleanb2 = indivial[++i];
if(b1 ==false&& b2 ==false) {
if(x >0&& labyrinth.map[y][x -1] ==true) {
x--;
if(!stack.isEmpty() && stack.peek()=="右")
stack.poll();
else
stack.push("左");
}
}elseif(b1 ==false&& b2 ==true) {
if(x +1< width && labyrinth.map[y][x +1] ==true) {
x++;
if(!stack.isEmpty() && stack.peek()=="左")
stack.poll();
else
stack.push("右");
}
}elseif(b1 ==true&& b2 ==false) {
if(y >0&& labyrinth.map[y -1][x] ==true) {
y--;
if(!stack.isEmpty() && stack.peek()=="下")
stack.poll();
else
stack.push("上");
}
}elseif(b1 ==true&& b2 ==true) {
if(y +1< height && labyrinth.map[y +1][x] ==true) {
y++;
if(!stack.isEmpty() && stack.peek()=="上")
stack.poll();
else
stack.push("下");
}
}
}
StringBuilder sb=newStringBuilder(length/4);
Iterator<String> iter=stack.descendingIterator();
while(iter.hasNext())
sb.append(iter.next());
returnsb.toString();
}
}
⑦ 标签传播算法为什么具有线性时间复杂度
计算公式:K(N)=AO(N)+B线性时间在计算复杂性理论,一个被称为线性时间或Ο(n)时间的算法,表示此算法解题所需时间正比于输入资料的大小,通常以n表示。换句话说,执行时间与输入资料大小为线性比例。例如将一列数字加总的所需时间,正比于串行的长度。