例一:简单加密
public class A
{
public static void main(String[] args) throws Exception
{
String s = "我们abc";
String key = "xyz";
byte[] key_buf = key.getBytes("utf-8");
//加密
byte[] buf = s.getBytes("utf-8");
for(int i=0; i<buf.length; i++){
buf[i] ^= key_buf[i%key_buf.length];
}
// 解密
for(int i=0; i<buf.length; i++){
buf[i] ^= key_buf[i%key_buf.length];
}
System.out.println(new String(buf, "utf-8"));
}
}
例二:完整简单加密
public class Simple
{
// buf 中的byte每个都转为16进制的串的表述形式
static String byteToAF(byte[] buf)
{
StringBuffer sb = new StringBuffer();
for(int i=0; i<buf.length; i++){
sb.append(String.format("%02X",buf[i]));
}
return sb.toString();
}
// 用16进制串形式表达的 byte,转换为byte数组
static byte[] AFtoByte(String s)
{
byte[] out = new byte[s.length()/2];
for(int i=0; i<s.length(); i+=2){
out[i/2] = (byte)(Character.getNumericValue(s.charAt(i)) * 16
+ Character.getNumericValue(s.charAt(i+1)));
}
return out;
}
// 加密过程
static String encrypt(String src, String key)
{
if(key.length()<1) return null;
try{
byte[] buf_txt = src.getBytes("utf-8");
byte[] buf_key = key.getBytes("utf-8");
for(int i=0; i<buf_txt.length; i++){
buf_txt[i] ^= buf_key[i%buf_key.length];
}
return byteToAF(buf_txt);
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
// 解密过程
static String decrypt(String src, String key)
{
if(key.length()<1) return null;
try{
byte[] buf_txt = AFtoByte(src);
byte[] buf_key = key.getBytes("utf-8");
for(int i=0; i<buf_txt.length; i++){
buf_txt[i] ^= buf_key[i%buf_key.length];
}
return new String(buf_txt,"utf-8");
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
public static void main(String[] args)
{
String s = encrypt("我们ab","xyz");
System.out.println(s);
String s2 = decrypt(s,"xyz");
System.out.println(s2);
}
}
例三:AES加密
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AES
{
public static String encrypt(String src, String pwd)
{
try {
// 处理密钥
byte[] bKey = pwd.getBytes("utf-8");
byte[] buf = new byte[16]; // 创建一个空的16位字节数组(默认值为0)
for (int i = 0; i < bKey.length && i < buf.length; i++) {
buf[i] = bKey[i];
}
SecretKeySpec key = new SecretKeySpec(buf, "AES");
// 加密
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] out = cipher.doFinal(src.getBytes("utf-8"));
//转为串
return new BASE64Encoder().encode(out);
}
catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static String decrypt(String src, String pwd)
{
try {
// 处理密钥
byte[] bKey = pwd.getBytes("utf-8");
byte[] buf = new byte[16]; // 创建一个空的16位字节数组(默认值为0)
for (int i = 0; i < bKey.length && i < buf.length; i++) {
buf[i] = bKey[i];
}
SecretKeySpec key = new SecretKeySpec(buf, "AES");
// 密文还原为byte[]
buf = new BASE64Decoder().decodeBuffer(src);
// 解密
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] out = cipher.doFinal(buf);
// 转为串
return new String(out,"utf-8");
}
catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static void main(String[] args) throws Exception
{
String s = "1中国人abc";
String s2 = encrypt(s,"xyz1");
System.out.println(s2);
String s3 = decrypt(s2,"xyz1");
System.out.println(s3);
}
}
例四:
/*设计程序
一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如下:
1.首先按行填入密钥串。
2.紧接其后,按字母序按行填入不在密钥串中的字母。
3.由于方阵中只有25个位置,最后剩下的那个字母则不需变换。
如果密钥为youandme,则该方阵如下:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
在加密一对字母时,如am,在方阵中找到以这两个字母为顶点的矩形(红色字体):
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
这对字母的加密字母为该矩形的另一对顶点,如本例中为ob。
请设计程序,使用上述方法对输入串进行加密,并输出加密后的串。
另外有如下规定:
1、一对一对取字母,如果最后只剩下一个字母,则不变换,直接放入加密串中;
2、如果一对字母中的两个字母相同,则不变换,直接放入加密串中;
3、如果一对字母中有一个字母不在正方形中,则不变换,直接放入加密串中;
4、如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母,即变换为fd或ih;
5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
6、本程序中输入串均为小写字母,并不含标点、空格或其它字符。
解密方法与加密相同,即对加密后的字符串再加密,将得到原始串。
要求输入形式如下:
从控制台输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50),两行字符串末尾都有一个回车换行符,并且两行字符串均为小写字母,不含其它字符。
在标准输出上输出加密后的字符串。
例如,若输入:
youandme
welcometohangzhou
则表示输入的密钥单词为youandme,形成的正方形如上所示;待加密字符串为welcometohangzhou。在正方形中可以找到以第一对字母we为顶点的矩形,对应另一对顶点字母为vb,因此加密后为vb,同理可找到与字母对lc,et,oh,ho对应的顶点字母对。而字母对om位于上述正方形中的同一列,所以直接以颠倒这两个字母来加密,即为mo,字母对an同理。字母对gz中的z不在上述正方形中,因此原样放到加密串中。最后剩一个字母u也原样输出。
因此输出的结果为:
vbrmmomvugnagzguu*/
public class C6 {
static char [][] key = new char[5][5];//5x5的方阵
static int [] alp = new int[26];//字母表,表示26个字母是否已经出现,-1表示没有出现过,i>-1表示已经出现,i/5为在方阵的横坐标,i%5为在方阵的纵坐标
//将密匙转化为5x5的方阵
public static void change(char []ckey) {
for(int i = 0; i < 26; ++i)//字母表初始化
alp[i] = -1;
// 按行填入密钥串
for (int ix = 0; ix < ckey.length; ++ix) {
key[ix / 5][ix % 5] = ckey[ix];
switch (ckey[ix]) {// 密钥中出现的字母,置为true
case 'a':
alp['a' - 'a'] = ix;
break;
case 'b':
alp['b' - 'a'] = ix;
break;
case 'c':
alp['c' - 'a'] = ix;
break;
case 'd':
alp['d' - 'a'] = ix;
break;
case 'e':
alp['e' - 'a'] = ix;
break;
case 'f':
alp['f' - 'a'] = ix;
break;
case 'g':
alp['g' - 'a'] = ix;
break;
case 'h':
alp['h' - 'a'] = ix;
break;
case 'i':
alp['i' - 'a'] = ix;
break;
case 'j':
alp['j' - 'a'] = ix;
break;
case 'k':
alp['k' - 'a'] = ix;
break;
case 'l':
alp['l' - 'a'] = ix;
break;
case 'm':
alp['m' - 'a'] = ix;
break;
case 'n':
alp['n' - 'a'] = ix;
break;
case 'o':
alp['o' - 'a'] = ix;
break;
case 'p':
alp['p' - 'a'] = ix;
break;
case 'q':
alp['q' - 'a'] = ix;
break;
case 'r':
alp['r' - 'a'] = ix;
break;
case 's':
alp['s' - 'a'] = ix;
break;
case 't':
alp['t' - 'a'] = ix;
break;
case 'u':
alp['u' - 'a'] = ix;
break;
case 'v':
alp['v' - 'a'] = ix;
break;
case 'w':
alp['w' - 'a'] = ix;
break;
case 'x':
alp['x' - 'a'] = ix;
break;
case 'y':
alp['y' - 'a'] = ix;
break;
case 'z':
alp['z' - 'a'] = ix;
break;
default:
break;
}
}
// 紧接其后,按字母序按行填入不在密钥串中的字母
for (int j = ckey.length, k = 0; j < 25 && k < 26; ++j, ++k) {
// 不在密钥串中的字母
if (alp[k] == -1) {
key[j / 5][j % 5] = (char) (k + 'a');
alp[k] = j;
} else {
j--;
}
}
// 输出转化过 的5*5的矩阵
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
System.out.print(key[i][j] + " ");
}
System.out.println();
}
}
// 加密过程
public static String encrypt (String pair, String s){
// 处理密钥
char []ckey = pair.toCharArray();//密匙
change(ckey);//将密匙转化为5x5的方阵
char [] c_s = s.toCharArray();
//从待加密字符串取每对字母加密
for(int i = 1; i < c_s.length; i += 2){//1
//2如果一对字母中的两个字母相同,则不变换,直接放入加密串中;3或一对字母中有一个字母不在正方形中 时则不变换,直接放入加密串中
if(c_s[i-1] == c_s[i] || (alp[c_s[i-1] - 'a'] == -1) || (alp[c_s[i] - 'a'] == -1))
continue;
//两个字母都在在正方形中且一对字母中的两个字母不同
else {
int row1 = alp[c_s[i-1] - 'a'] / 5;//一对字母中的第一个字母横坐标
int clum1 = alp[c_s[i-1] - 'a'] % 5;//一对字母中的第一个字母纵坐标
int row2 = alp[c_s[i] - 'a'] / 5;//一对字母中的第二个字母横坐标
int clum2 = alp[c_s[i] - 'a'] % 5;//一对字母中的第二个字母纵坐标
if(row1 == row2 || clum1 == clum2){//4如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母
char temp = c_s[i-1];
c_s[i-1] = c_s[i];
c_s[i] = temp;
}
//5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,
//在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
else{
c_s[i-1] = key[row1][clum2];
c_s[i] = key[row2][clum1];
}
}
/* if(c_s.length % 2 == 1 && i == c_s.length ){
break;
}*/
}
String s2 = new String(c_s);//存储加密过的字符串
return s2;
}
// 解密过程
public static String decrypt (String pair, String s){
// 处理密钥
char []ckey = pair.toCharArray();//密匙
change(ckey);//将密匙转化为5x5的方阵
char [] c_s = s.toCharArray();
//从待加密字符串取每对字母加密
for(int i = 1; i < c_s.length; i += 2){//1
//2如果一对字母中的两个字母相同,则不变换,直接放入加密串中;3或一对字母中有一个字母不在正方形中 时则不变换,直接放入加密串中
if(c_s[i-1] == c_s[i] || (alp[c_s[i-1] - 'a'] == -1) || (alp[c_s[i] - 'a'] == -1))
continue;
//两个字母都在在正方形中且一对字母中的两个字母不同
else {
int row1 = alp[c_s[i-1] - 'a'] / 5;//一对字母中的第一个字母横坐标
int clum1 = alp[c_s[i-1] - 'a'] % 5;//一对字母中的第一个字母纵坐标
int row2 = alp[c_s[i] - 'a'] / 5;//一对字母中的第二个字母横坐标
int clum2 = alp[c_s[i] - 'a'] % 5;//一对字母中的第二个字母纵坐标
if(row1 == row2 || clum1 == clum2){//4如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母
char temp = c_s[i-1];
c_s[i-1] = c_s[i];
c_s[i] = temp;
}
//5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,
//在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
else{
c_s[i-1] = key[row1][clum2];
c_s[i] = key[row2][clum1];
}
}
/* if(c_s.length % 2 == 1 && i == c_s.length ){
break;
}*/
}
String s2 = new String(c_s);//存储加密过的字符串
return s2;
}
public static void main(String[] args) {
String s;//待加密字符串
String pair;//密匙
Scanner scan = new Scanner(System.in);
System.out.println("请输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50):");
pair = scan.nextLine();
s = scan.nextLine();
String s2 = encrypt(pair, s);
String s3 = decrypt (pair, s2);
System.out.println("加密过的字符串:");
System.out.println(s2);
System.out.println("解密过的字符串:");
System.out.println(s3);
}
}