最近因业务关系,开始正儿八经的学java。因为C的背景,先入为主, 就和C做比较学习。
/*Struct.java -- how C to java
* OO 的四大要素: 抽象,封装,模块化,分层
* Java 的优点:
* 安全性:
* 1. 引用必须初始化;
* 2. 数组下标检查;
* 3. 死机时优雅的打印StackTrace。
* 其他优点以后涉及到时再说。
*
* author: ludi 2014.03*/
import java.lang.System; /*目录分层结构,C中没有语法上的支持*/
class Type{/*C中的Struct抽象封装*/
public int a, b;
public void change(){/*C++中的Struct*/
this.a += 1;
this.b += 2;
}
}
public class Struct{/*必须和文件名一样: 编译器强制模块化*/
static void change(Type t){/*跟对象实例无关的函数必须是static*/
t.a += 1; /*C++中的引用传递*/
t.b += 2; /*如何打印引用的内存地址?*/
int[] x = {1,2,3,4}; /*数组定义比C中的int[4],类型更具有一致性*/
Type[] y = {null, null, null}; /*y数组是在堆上分配么?如何释放?*/
}
public static void main(String[] args){
Type t = new Type(); /*编译器强制引用必须初始化*/
//System.printf("a = %d b = %d\n", t.a, t.b); /**/
System.out.println(t.a + " " + t.b); /*安全的打印*/
change(t); /*引用就是指针*/
t.change(); /*提倡这样用才是OO style*/
System.out.println(t.a + " " + t.b);
}
}
以前跟风别人说java语法比较啰嗦,特别是看了某些一上来就写莫某设计模式的时候。现在看来是写代码的人没有做好抽象这一步了。当然非要看hello world 最短, C也比不上perl之类的。
从实用主义的观点,给第一个应用例子, RSA加密和解密:
/*RSA.java -- using RSA do encryption and decryption
* java 优点:
* 有标准的包:BigInteger
*
* author: ludi 2014.03
* */
import java.math.*;
import java.util.*;
public class RSA{
public static BigInteger relativePrime(BigInteger t)
{/*return number k, such that gcd(k,t) = 1.*/
BigInteger k = null;
Random rnd = new Random();
do{
k = new BigInteger(64, rnd); /*generate a random k \in (0, 2^64)*/
}while(!t.gcd(k).equals(BigInteger.ONE));
return k;
}
public static void main(String[] args){
if(args.length < 1){
System.out.println("usage: RSA message\n");
return;
}
Random rnd = new Random();
BigInteger p = null, q = null, n = null, t = null, e = null, d = null,
one = BigInteger.ONE,
raw = null, encrypted = null, decrypted = null;
String msg = null;
p = BigInteger.probablePrime(128, rnd); /*bit length = 128*/
q = BigInteger.probablePrime(128, rnd);
n = p.multiply(q);
t = (p.subtract(one)).multiply(q.subtract(one));
e = relativePrime(t);
d = e.modInverse(t);
raw = new BigInteger(args[0].getBytes());/*bit stream*/
encrypted = raw.modPow(e, n);
decrypted = encrypted.modPow(d, n);
//System.out.println("raw integer: " + raw
// + "\np = " + p + "\nq = " + q);
System.out.println("raw message: ‘" + args[0] + "‘");
msg = new String(encrypted.toByteArray());
System.out.println("encrypted: ‘" + msg + "‘");
msg = new String(decrypted.toByteArray());
System.out.println("decrypted: ‘" + msg + "‘");
System.out.println("public key = (n,e), private key = (n,d)");
System.out.println("n = " + n);
System.out.println("e = " + e);
System.out.println("d = " + d);
}
}
/*
ludi@ubun:~
$ java RSA ‘Pay $123.45‘
raw message: ‘Pay $123.45‘
encrypted: ‘E?????xs>?????-W?G??r蕎??h]‘
decrypted: ‘Pay $123.45‘
public key = (n,e), private key = (n,d)
n = 49501839457986030455953244525444742182049040819775728995411857641724770216969
e = 772464604889112363
d = 5561519969026911507015137142430098280107716226986092378589977153350026908067
ludi@ubun:~
$
由于是随机的,每次运行的n,e,d可能都不同。
p,q,k 的长度取多少合适?
RSA 定理: 设 n = p * q, t = (p - 1)*(q - 1), e 与t 互素,1 = e*d(mod t),
则 对于任何0 < a < n, 有a = a^(e*d) (mod n)。
代码中的n长度 = 128+128-1 = 255。如果输入"12", 则a = 0x3132。
即一个字符对应到8bit长,因此输入字符串长度应当小于 255/8 = 36。
e限定到64bit,应该是可以的(定理?)。通常是服务器生成密钥,
把公钥(n,e)发给客户端,客户端加密,较小的e使得客户端运算量小些。
*/
后续打算继续贴上,我学习java版的数据结构方面的。
原文:http://blog.csdn.net/deyangliu/article/details/20945499