A. java排列組合的演算法 譬如我有(A,B,C,D),我想輸出的結果是
我覺得可以看成數字的排列如 1 2 3 4分別代表A B C D
就是將1 2 3 4排列
四位的就是1234
三位的就是從這四個數字中取出三個數字,得到的三位數是最小的,如:
取 1 2 3 可以得到123 213 321 132等等 其中123是最小的
兩為數字的跟三位數字的一樣
B. 如何用java編程計算
你是問演算法 還是帶界面?
package Counter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
class pbl extends Frame
{
double x,y,a,b;
int z;
GridLayout gl1,gl2,gl3,gl4;
Button btn0,btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn10,btn11,btn12,btn13,btn14,btn15,btn16,btn17;
JTextField tf1;
StringBuffer str;
Panel p1,p2,p3,p4;
public pbl()
{
JFrame jf=new JFrame("計算器");
jf.setSize(180,280);
jf.setLocation(150,150);
gl1=new GridLayout(1,1,5,5);
gl2=new GridLayout(5,3,5,5);
gl3=new GridLayout(3,1,5,5);
gl4=new GridLayout(1,1,5,5);
p1=new Panel();
p1.setLayout(gl1);
tf1=new JTextField("0");
tf1.setHorizontalAlignment(JTextField.RIGHT);
p1.add(tf1);
p1.setBounds(10, 20,153, 30);
tf1.setEditable(false);
str=new StringBuffer();
btn1=new Button("1");
btn1.setForeground(Color.BLUE);
btn1.addActionListener(new ac());
btn2=new Button("2");
btn2.setForeground(Color.BLUE);
btn2.addActionListener(new ac());
btn3=new Button("3");
btn3.setForeground(Color.BLUE);
btn3.addActionListener(new ac());
btn4=new Button("4");
btn4.setForeground(Color.BLUE);
btn4.addActionListener(new ac());
btn5=new Button("5");
btn5.setForeground(Color.BLUE);
btn5.addActionListener(new ac());
btn6=new Button("6");
btn6.setForeground(Color.BLUE);
btn6.addActionListener(new ac());
btn7=new Button("7");
btn7.setForeground(Color.BLUE);
btn7.addActionListener(new ac());
btn8=new Button("8");
btn8.setForeground(Color.BLUE);
btn8.addActionListener(new ac());
btn9=new Button("9");
btn9.setForeground(Color.BLUE);
btn9.addActionListener(new ac());
btn0=new Button("0");
btn0.setForeground(Color.BLUE);
btn0.addActionListener(new ac());
btn10=new Button("+");
btn10.setForeground(Color.RED);
btn10.addActionListener(new ac());
btn11=new Button("-");
btn11.setForeground(Color.RED);
btn11.addActionListener(new ac());
btn12=new Button("*");
btn12.setForeground(Color.red);
btn12.addActionListener(new ac());
btn13=new Button("/");
btn13.setForeground(Color.RED);
btn13.addActionListener(new ac());
btn14=new Button(".");
btn14.setForeground(Color.RED);
btn14.addActionListener(new ac());
btn15=new Button("+/-");
btn15.setForeground(Color.RED);
btn15.addActionListener(new ac());
btn16=new Button("CE");
btn16.setForeground(Color.RED);
btn16.addActionListener(new ac());
btn17=new Button("=");
btn17.setForeground(Color.RED);
btn17.addActionListener(new ac());
p2=new Panel();
p2.setLayout(gl2);
p2.add(btn16);
p2.add(btn13);
p2.add(btn12);
p2.add(btn1);
p2.add(btn2);
p2.add(btn3);
p2.add(btn4);
p2.add(btn5);
p2.add(btn6);
p2.add(btn7);
p2.add(btn8);
p2.add(btn9);
p2.add(btn0);
p2.add(btn14);
p2.add(btn15);
p2.setBounds(10, 75, 120, 150);
p3=new Panel();
p3.setLayout(gl3);
p3.add(btn10);
p3.add(btn17);
p3.setBounds(133,105,30,182);
p4=new Panel();
p4.setLayout(gl4);
p4.add(btn11);
p4.setBounds(133, 75, 30, 26);
jf.setLayout(null);
jf.setResizable(false);
jf.add(p1);
jf.add(p2);
jf.add(p3);
jf.add(p4);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class ac implements ActionListener
{
public void actionPerformed(ActionEvent ce)
{
if(ce.getSource()==btn16)
{
tf1.setText("0");//ce
str.setLength(0);
}
else if(ce.getSource()==btn15)//(+/-)
{
a=Double.parseDouble(tf1.getText());
//a*=-1;
tf1.setText(""+(-a));
}
else if(ce.getSource()==btn14)//(.)
{
if(tf1.getText().trim().indexOf(".")!=-1)
{
}
else if(tf1.getText().trim().equals("0"))
{
tf1.setText("0"+str.append(ce.getActionCommand()).toString());
}
else
{
tf1.setText(str.append(ce.getActionCommand()).toString());
}
}
else if(ce.getSource()==btn10)//(+)
{
x=Double.parseDouble(tf1.getText().trim());
str.setLength(0);
y=0;
z=1;
}
else if(ce.getSource()==btn11)//(-)
{
x=Double.parseDouble(tf1.getText().trim());
str.setLength(0);
y=0;
z=2;
}
else if(ce.getSource()==btn12)//(*)
{
x=Double.parseDouble(tf1.getText().trim());
str.setLength(0);
y=0;
z=3;
}
else if(ce.getSource()==btn13)//(/)
{
x=Double.parseDouble(tf1.getText().trim());
str.setLength(0);
y=0;
z=4;
}
else if(ce.getSource()==btn17)//(=)
{
str.setLength(0);
y=Double.parseDouble(tf1.getText().trim());
switch (z)
{
case 1: tf1.setText(""+(x+y)) ;break;
case 2: tf1.setText(""+(x-y)) ;break;
case 3: tf1.setText(""+(x*y)) ;break;
case 4: tf1.setText(""+(x/y)) ;break;
}
z=0;
}
else
{
tf1.setText(str.append(ce.getActionCommand()).toString());
}
}
}
public static void main(String[] args)
{
new pbl();
}
}
C. java最常用的幾種加密演算法
簡單的Java加密演算法有:
第一種. BASE
Base是網路上最常見的用於傳輸Bit位元組代碼的編碼方式之一,大家可以查看RFC~RFC,上面有MIME的詳細規范。Base編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base來將一個較長的唯一標識符(一般為-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
第二種. MD
MD即Message-Digest Algorithm (信息-摘要演算法),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD的前身有MD、MD和MD。
MD演算法具有以下特點:
壓縮性:任意長度的數據,算出的MD值長度都是固定的。
容易計算:從原數據計算出MD值很容易。
抗修改性:對原數據進行任何改動,哪怕只修改個位元組,所得到的MD值都有很大區別。
弱抗碰撞:已知原數據和其MD值,想找到一個具有相同MD值的數據(即偽造數據)是非常困難的。
強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD值,是非常困難的。
MD的作用是讓大容量信息在用數字簽名軟體簽署私人密鑰前被」壓縮」成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進制數字串)。除了MD以外,其中比較有名的還有sha-、RIPEMD以及Haval等。
第三種.SHA
安全哈希演算法(Secure Hash Algorithm)主要適用於數字簽名標准(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度小於^位的消息,SHA會產生一個位的消息摘要。該演算法經過加密專家多年來的發展和改進已日益完善,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或信息),並把它們轉化為長度較短、位數固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程。散列函數值可以說是對明文的一種「指紋」或是「摘要」所以對散列值的數字簽名就可以視為對此明文的數字簽名。
SHA-與MD的比較
因為二者均由MD導出,SHA-和MD彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同:
對強行攻擊的安全性:最顯著和最重要的區別是SHA-摘要比MD摘要長 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對MD是^數量級的操作,而對SHA-則是^數量級的操作。這樣,SHA-對強行攻擊有更大的強度。
對密碼分析的安全性:由於MD的設計,易受密碼分析的攻擊,SHA-顯得不易受這樣的攻擊。
速度:在相同的硬體上,SHA-的運行速度比MD慢。
第四種.HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。
D. 用java怎麼實現A*演算法
代碼實現(Java)
1.輸入
(1)代表地圖二值二維數組(0表示可通路,1表示路障)
int[][]maps={
{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,1,1,0,0,0,0,0,0,1,1,1,0,0},
{0,0,0,1,0,0,0,0,0,1,1,0,0,0,0},
{0,0,0,1,0,0,0,0,1,1,0,0,0,0,0},
{0,0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,1,0,0,0,0,0,0}
};123456789123456789
(2)按照二維數組的特點,坐標原點在左上角,所以y是高,x是寬,y向下遞增,x向右遞增,我們將x和y封裝成一個類,好傳參,重寫equals方法比較坐標(x,y)是不是同一個。
publicclassCoord
{
publicintx;
publicinty;
publicCoord(intx,inty)
{
this.x=x;
this.y=y;
}
@Override
publicbooleanequals(Objectobj)
{
if(obj==null)returnfalse;
if(objinstanceofCoord)
{
Coordc=(Coord)obj;
returnx==c.x&&y==c.y;
}
returnfalse;
}
}2223
(3)封裝路徑結點類,欄位包括:坐標、G值、F值、父結點,實現Comparable介面,方便優先隊列排序。
<Node>
{
publicCoordcoord;//坐標
publicNodeparent;//父結點
publicintG;//G:是個准確的值,是起點到當前結點的代價
publicintH;//H:是個估值,當前結點到目的結點的估計代價
publicNode(intx,inty)
{
this.coord=newCoord(x,y);
}
publicNode(Coordcoord,Nodeparent,intg,inth)
{
this.coord=coord;
this.parent=parent;
G=g;
H=h;
}
@Override
publicintcompareTo(Nodeo)
{
if(o==null)return-1;
if(G+H>o.G+o.H)
return1;
elseif(G+H<o.G+o.H)return-1;
return0;
}
}
(4)最後一個數據結構是A星演算法輸入的所有數據,封裝在一起,傳參方便。:grin:
publicclassMapInfo
{
publicint[][]maps;//二維數組的地圖
publicintwidth;//地圖的寬
publicinthight;//地圖的高
publicNodestart;//起始結點
publicNodeend;//最終結點
publicMapInfo(int[][]maps,intwidth,inthight,Nodestart,Nodeend)
{
this.maps=maps;
this.width=width;
this.hight=hight;
this.start=start;
this.end=end;
}
}
2.處理
(1)在演算法里需要定義幾個常量來確定:二維數組中哪個值表示障礙物、二維數組中繪制路徑的代表值、計算G值需要的橫縱移動代價和斜移動代價。
publicfinalstaticintBAR=1;//障礙值
publicfinalstaticintPATH=2;//路徑
publicfinalstaticintDIRECT_VALUE=10;//橫豎移動代價
publicfinalstaticintOBLIQUE_VALUE=14;//斜移動代價12341234
(2)定義兩個輔助表:Open表和Close表。Open表的使用是需要取最小值,在這里我們使用Java工具包中的優先隊列PriorityQueue,Close只是用來保存結點,沒其他特殊用途,就用ArrayList。
Queue<Node>openList=newPriorityQueue<Node>();//優先隊列(升序)
List<Node>closeList=newArrayList<Node>();1212
(3)定義幾個布爾判斷方法:最終結點的判斷、結點能否加入open表的判斷、結點是否在Close表中的判斷。
/**
*判斷結點是否是最終結點
*/
privatebooleanisEndNode(Coordend,Coordcoord)
{
returncoord!=null&&end.equals(coord);
}
/**
*判斷結點能否放入Open列表
*/
(MapInfomapInfo,intx,inty)
{
//是否在地圖中
if(x<0||x>=mapInfo.width||y<0||y>=mapInfo.hight)returnfalse;
//判斷是否是不可通過的結點
if(mapInfo.maps[y][x]==BAR)returnfalse;
//判斷結點是否存在close表
if(isCoordInClose(x,y))returnfalse;
returntrue;
}
/**
*判斷坐標是否在close表中
*/
privatebooleanisCoordInClose(Coordcoord)
{
returncoord!=null&&isCoordInClose(coord.x,coord.y);
}
/**
*判斷坐標是否在close表中
*/
privatebooleanisCoordInClose(intx,inty)
{
if(closeList.isEmpty())returnfalse;
for(Nodenode:closeList)
{
if(node.coord.x==x&&node.coord.y==y)
{
returntrue;
}
}
returnfalse;
}353637383940414243444546
(4)計算H值,「曼哈頓」法,坐標分別取差值相加
privateintcalcH(Coordend,Coordcoord)
{
returnMath.abs(end.x-coord.x)+Math.abs(end.y-coord.y);
}12341234
(5)從Open列表中查找結點
privateNodefindNodeInOpen(Coordcoord)
{
if(coord==null||openList.isEmpty())returnnull;
for(Nodenode:openList)
{
if(node.coord.equals(coord))
{
returnnode;
}
}
returnnull;
}
(6)添加鄰結點到Open表
/**
*添加所有鄰結點到open表
*/
(MapInfomapInfo,Nodecurrent)
{
intx=current.coord.x;
inty=current.coord.y;
//左
addNeighborNodeInOpen(mapInfo,current,x-1,y,DIRECT_VALUE);
//上
addNeighborNodeInOpen(mapInfo,current,x,y-1,DIRECT_VALUE);
//右
addNeighborNodeInOpen(mapInfo,current,x+1,y,DIRECT_VALUE);
//下
addNeighborNodeInOpen(mapInfo,current,x,y+1,DIRECT_VALUE);
//左上
addNeighborNodeInOpen(mapInfo,current,x-1,y-1,OBLIQUE_VALUE);
//右上
addNeighborNodeInOpen(mapInfo,current,x+1,y-1,OBLIQUE_VALUE);
//右下
addNeighborNodeInOpen(mapInfo,current,x+1,y+1,OBLIQUE_VALUE);
//左下
addNeighborNodeInOpen(mapInfo,current,x-1,y+1,OBLIQUE_VALUE);
}
/**
*添加一個鄰結點到open表
*/
(MapInfomapInfo,Nodecurrent,intx,inty,intvalue)
{
if(canAddNodeToOpen(mapInfo,x,y))
{
Nodeend=mapInfo.end;
Coordcoord=newCoord(x,y);
intG=current.G+value;//計算鄰結點的G值
Nodechild=findNodeInOpen(coord);
if(child==null)
{
intH=calcH(end.coord,coord);//計算H值
if(isEndNode(end.coord,coord))
{
child=end;
child.parent=current;
child.G=G;
child.H=H;
}
else
{
child=newNode(coord,current,G,H);
}
openList.add(child);
}
elseif(child.G>G)
{
child.G=G;
child.parent=current;
//重新調整堆
openList.add(child);
}
}
}85960618596061
(7)回溯法繪制路徑
privatevoiddrawPath(int[][]maps,Nodeend)
{
if(end==null||maps==null)return;
System.out.println("總代價:"+end.G);
while(end!=null)
{
Coordc=end.coord;
maps[c.y][c.x]=PATH;
end=end.parent;
}
}12345678910111234567891011
(8)開始演算法,循環移動結點尋找路徑,設定循環結束條件,Open表為空或者最終結點在Close表
publicvoidstart(MapInfomapInfo)
{
if(mapInfo==null)return;
//clean
openList.clear();
closeList.clear();
//開始搜索
openList.add(mapInfo.start);
moveNodes(mapInfo);
}
/**
*移動當前結點
*/
privatevoidmoveNodes(MapInfomapInfo)
{
while(!openList.isEmpty())
{
if(isCoordInClose(mapInfo.end.coord))
{
drawPath(mapInfo.maps,mapInfo.end);
break;
}
Nodecurrent=openList.poll();
closeList.add(current);
addNeighborNodeInOpen(mapInfo,current);
}
}
E. 幾種加密演算法在java中的應用
簡單的Java加密演算法有:
第一種. BASE
Base是網路上最常見的用於傳輸Bit位元組代碼的編碼方式之一,大家可以查看RFC~RFC,上面有MIME的詳細規范。Base編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base來將一個較長的唯一標識符(一般為-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
第二種. MD
MD即Message-Digest Algorithm (信息-摘要演算法),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD的前身有MD、MD和MD。廣泛用於加密和解密技術,常用於文件校驗。校驗?不管文件多大,經過MD後都能生成唯一的MD值。好比現在的ISO校驗,都是MD校驗。怎麼用?當然是把ISO經過MD後產生MD的值。一般下載linux-ISO的朋友都見過下載鏈接旁邊放著MD的串。就是用來驗證文件是否一致的。
MD演算法具有以下特點:
壓縮性:任意長度的數據,算出的MD值長度都是固定的。
容易計算:從原數據計算出MD值很容易。
抗修改性:對原數據進行任何改動,哪怕只修改個位元組,所得到的MD值都有很大區別。
弱抗碰撞:已知原數據和其MD值,想找到一個具有相同MD值的數據(即偽造數據)是非常困難的。
強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD值,是非常困難的。
MD的作用是讓大容量信息在用數字簽名軟體簽署私人密鑰前被」壓縮」成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進制數字串)。除了MD以外,其中比較有名的還有sha-、RIPEMD以及Haval等。
第三種.SHA
安全哈希演算法(Secure Hash Algorithm)主要適用於數字簽名標准(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度小於^位的消息,SHA會產生一個位的消息摘要。該演算法經過加密專家多年來的發展和改進已日益完善,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或信息),並把它們轉化為長度較短、位數固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程。散列函數值可以說是對明文的一種「指紋」或是「摘要」所以對散列值的數字簽名就可以視為對此明文的數字簽名。
SHA-與MD的比較
因為二者均由MD導出,SHA-和MD彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同:
對強行攻擊的安全性:最顯著和最重要的區別是SHA-摘要比MD摘要長 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對MD是^數量級的操作,而對SHA-則是^數量級的操作。這樣,SHA-對強行攻擊有更大的強度。
對密碼分析的安全性:由於MD的設計,易受密碼分析的攻擊,SHA-顯得不易受這樣的攻擊。
速度:在相同的硬體上,SHA-的運行速度比MD慢。
第四種.HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。
F. 分享Java常用幾種加密演算法
簡單的Java加密演算法有:
第一種. BASE
Base是網路上最常見的用於傳輸Bit位元組代碼的編碼方式之一,大家可以查看RFC~RFC,上面有MIME的詳細規范。Base編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base來將一個較長的唯一標識符(一般為-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
第二種. MD
MD即Message-Digest Algorithm (信息-摘要演算法),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD的前身有MD、MD和MD。廣泛用於加密和解密技術,常用於文件校驗。校驗?不管文件多大,經過MD後都能生成唯一的MD值。好比現在的ISO校驗,都是MD校驗。怎麼用?當然是把ISO經過MD後產生MD的值。一般下載linux-ISO的朋友都見過下載鏈接旁邊放著MD的串。就是用來驗證文件是否一致的。
MD演算法具有以下特點:
壓縮性:任意長度的數據,算出的MD值長度都是固定的。
容易計算:從原數據計算出MD值很容易。
抗修改性:對原數據進行任何改動,哪怕只修改個位元組,所得到的MD值都有很大區別。
弱抗碰撞:已知原數據和其MD值,想找到一個具有相同MD值的數據(即偽造數據)是非常困難的。
強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD值,是非常困難的。
MD的作用是讓大容量信息在用數字簽名軟體簽署私人密鑰前被」壓縮」成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進制數字串)。除了MD以外,其中比較有名的還有sha-、RIPEMD以及Haval等。
第三種.SHA
安全哈希演算法(Secure Hash Algorithm)主要適用於數字簽名標准(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度小於^位的消息,SHA會產生一個位的消息摘要。該演算法經過加密專家多年來的發展和改進已日益完善,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或信息),並把它們轉化為長度較短、位數固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程。散列函數值可以說是對明文的一種「指紋」或是「摘要」所以對散列值的數字簽名就可以視為對此明文的數字簽名。
SHA-與MD的比較
因為二者均由MD導出,SHA-和MD彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同:
對強行攻擊的安全性:最顯著和最重要的區別是SHA-摘要比MD摘要長 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對MD是^數量級的操作,而對SHA-則是^數量級的操作。這樣,SHA-對強行攻擊有更大的強度。
對密碼分析的安全性:由於MD的設計,易受密碼分析的攻擊,SHA-顯得不易受這樣的攻擊。
速度:在相同的硬體上,SHA-的運行速度比MD慢。
第四種.HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。
G. 學JAVA的適合參加ACM嗎
可以的,人家俄羅斯的petr大牛都用著java參加topcoder。java有些庫在acm上用挺不錯的。ACM出思路快比較重要,我用java寫和c++寫長度差不了很多,主要時間在思考上。java速度當然沒有C++快,在某些變態的題目中被卡算你運氣不好,一般而言對java的時空要求是放寬了的,正確的演算法就能AC
H. java有哪些垃圾回收演算法
常用的垃圾回收演算法有:
(1).引用計數演算法:
給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器都為0的對象就是不再被使用的,垃圾收集器將回收該對象使用的內存。
引用計數演算法實現簡單,效率很高,微軟的COM技術、ActionScript、Python等都使用了引用計數演算法進行內存管理,但是引用計數演算法對於對象之間相互循環引用問題難以解決,因此java並沒有使用引用計數演算法。
(2).根搜索演算法:
通過一系列的名為「GC Root」的對象作為起點,從這些節點向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當一個對象到GC Root沒有任何引用鏈相連時,則該對象不可達,該對象是不可使用的,垃圾收集器將回收其所佔的內存。
主流的商用程序語言C#、java和Lisp都使用根搜素演算法進行內存管理。
在java語言中,可作為GC Root的對象包括以下幾種對象:
a. java虛擬機棧(棧幀中的本地變數表)中的引用的對象。
b.方法區中的類靜態屬性引用的對象。
c.方法區中的常量引用的對象。
d.本地方法棧中JNI本地方法的引用對象。
java方法區在Sun HotSpot虛擬機中被稱為永久代,很多人認為該部分的內存是不用回收的,java虛擬機規范也沒有對該部分內存的垃圾收集做規定,但是方法區中的廢棄常量和無用的類還是需要回收以保證永久代不會發生內存溢出。
判斷廢棄常量的方法:如果常量池中的某個常量沒有被任何引用所引用,則該常量是廢棄常量。
判斷無用的類:
(1).該類的所有實例都已經被回收,即java堆中不存在該類的實例對象。
(2).載入該類的類載入器已經被回收。
(3).該類所對應的java.lang.Class對象沒有任何地方被引用,無法在任何地方通過反射機制訪問該類的方法。
Java中常用的垃圾收集演算法:
(1).標記-清除演算法:
最基礎的垃圾收集演算法,演算法分為「標記」和「清除」兩個階段:首先標記出所有需要回收的對象,在標記完成之後統一回收掉所有被標記的對象。
標記-清除演算法的缺點有兩個:首先,效率問題,標記和清除效率都不高。其次,標記清除之後會產生大量的不連續的內存碎片,空間碎片太多會導致當程序需要為較大對象分配內存時無法找到足夠的連續內存而不得不提前觸發另一次垃圾收集動作。
(2).復制演算法:
將可用內存按容量分成大小相等的兩塊,每次只使用其中一塊,當這塊內存使用完了,就將還存活的對象復制到另一塊內存上去,然後把使用過的內存空間一次清理掉。這樣使得每次都是對其中一塊內存進行回收,內存分配時不用考慮內存碎片等復雜情況,只需要移動堆頂指針,按順序分配內存即可,實現簡單,運行高效。
復制演算法的缺點顯而易見,可使用的內存降為原來一半。
(3).標記-整理演算法:
標記-整理演算法在標記-清除演算法基礎上做了改進,標記階段是相同的標記出所有需要回收的對象,在標記完成之後不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,在移動過程中清理掉可回收的對象,這個過程叫做整理。
標記-整理演算法相比標記-清除演算法的優點是內存被整理以後不會產生大量不連續內存碎片問題。
復制演算法在對象存活率高的情況下就要執行較多的復制操作,效率將會變低,而在對象存活率高的情況下使用標記-整理演算法效率會大大提高。
(4).分代收集演算法:
根據內存中對象的存活周期不同,將內存劃分為幾塊,java的虛擬機中一般把內存劃分為新生代和年老代,當新創建對象時一般在新生代中分配內存空間,當新生代垃圾收集器回收幾次之後仍然存活的對象會被移動到年老代內存中,當大對象在新生代中無法找到足夠的連續內存時也直接在年老代中創建。
I. java中的演算法,一共有多少種,哪幾種,怎麼分類。
就好比問,漢語中常用寫作方法有多少種,怎麼分類。
演算法按用途分,體現設計目的、有什麼特點
演算法按實現方式分,有遞歸、迭代、平行、序列、過程、確定、不確定等等
演算法按設計范型分,有分治、動態、貪心、線性、圖論、簡化等等
作為圖靈完備的語言,理論上」Java語言「可以實現所有演算法。
「Java的標准庫'中用了一些常用數據結構和相關演算法.
像apache common這樣的java庫中又提供了一些通用的演算法
J. java遞歸演算法
1.漢諾塔問題
import javax.swing.JOptionPane;
public class Hanoi {
private static final String DISK_B = "diskB";
private static final String DISK_C = "diskC";
private static final String DISK_A = "diskA";
static String from=DISK_A;
static String to=DISK_C;
static String mid=DISK_B;
public static void main(String[] args) {
String input=JOptionPane.showInputDialog("please input the number of the disks you want me move.");
int num=Integer.parseInt(input);
move(num,from,mid,to);
}
private static void move(int num, String from2, String mid2, String to2) {
if(num==1){
System.out.println("move disk 1 from "+from2+" to "+to2);
}
else {
move(num-1,from2,to2,mid2);
System.out.println("move disk "+num+" from "+from2+" to "+to2);
move(num-1,mid2,from2,to2);
}
}
}
2. 這是一個排列的例子,它所做的工作是將輸入的一個字元串中的所有元素進行排序並輸出,例如:你給出的參數是"abc" 則程序會輸出:
abc
acb
bac
bca
cab
cba
(1)演算法的出口在於:low=high也就是現在給出的排列元素只有一個時。
(2)演算法的逼近過程:先確定排列的第一位元素,也就是循環中i所代表的元素,
然後low+1開始減少排列元素,如此下去,直到low=high
public static void permute(String str) {
char[] strArray = str.toCharArray();
permute(strArray, 0, strArray.length - 1);
}
public static void permute(char[] list, int low, int high) {
int i;
if (low == high) {
String cout = "";
for (i = 0; i <= high; i++)
cout += list[i];
System.out.println(cout);
} else {
for (i = low; i <= high; i++) {
char temp = list[low];
list[low] = list[i];
list[i] = temp;
permute(list, low + 1, high);
temp = list[low];
list[low] = list[i];
list[i] = temp;
}
}
}
3。這是一個組合的例子,與上述的例子相似,只是它所做的工作是,輸出所給字元串中制定數目的元素的組合種類
(1)程序出口在於n=1,此時只要輸出目標數組的所有元素即可
(2)逼近過程,當n>1的時候,我們先取第一個元素放入目標數組中,然後n-1,如此下去,最後出來。
import javax.swing.JOptionPane;
public class Combination {
/**
* @param args
*/
public static void main(String[] args) {
String input = JOptionPane.showInputDialog("please input your String: ");
String numString = JOptionPane.showInputDialog("please input the number of your Combination: ");
int num = Integer.parseInt(numString);
Combine(input, num);
}
private static void Combine(String input, int num) {
char[] a = input.toCharArray();
String b = "";
Combine(a, num, b, 0, a.length);
}
private static void Combine(char[] a, int num, String b, int low, int high) {
if (num == 0) {
System.out.println(b);
} else {
for (int i = low; i < a.length; i++) {
b += a[i];
Combine(a, num - 1, b, i+1, a.length);
b=b.substring(0, b.length()-1);
}
}
}
}