知识大全 JAVA编程语言开发DES算法理论
Posted 字节
篇首语:水滴集多成大海,读书集多成学问。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 JAVA编程语言开发DES算法理论相关的知识,希望对你有一定的参考价值。
JAVA编程语言开发DES算法理论 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
[java]
/**
* DES算法理论
本世纪五十年代以来 密码学研究领域出现了最具代表性的两大成就 其中之一就是 年美国学者塔奇曼 (Tuchman)和麦耶(Meyer)根据信息论创始人香农(Shannon)提出的「多重加密有效性理论」创立的 后于 年由美国国家标准局颁布的数据加密标准
DES密码实际上是Lucifer密码的进一步发展 它是一种采用传统加密方法的区组密码 它的算法是对称的 既可用于加密又可用于解密
美国国家标准局 年开始研究除国防部外的其它部门的计算机系统的数据加密标准 于 年 月 日和 年 月 日先后两次向公众发出了征求加密算法的公告 加密算法要达到的目的通常称为DES密码算法要求主要为以下四点
提供高质量的数据保护 防止数据未经授权的泄露和未被察觉的修改 具有相当高的复杂性 使得破译的开销超过可能获得的利益 同时又要便于理解和掌握 DES密码体制的安全性应该不依赖于算法的保密 其安全性仅以加密密钥的保密为基础实现经济 运行有效 并且适用于多种完全不同的应用
年 月 美国政府颁布 采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES枣Data Encryption Standard)
目前在这里 随着三金工程尤其是金卡工程的启动 DES算法在POS ATM 磁卡及智能卡(IC卡) 加油站 高速公路收费站等领域被广泛应用 以此来实现关键数据的保密 如信用卡持卡人的PIN的加密传输 IC卡与POS间的双向认证 金融交易数据包的MAC校验等 均用到DES算法
DES算法的入口参数有三个 Key Data Mode 其中Key为 个字节共 位 是DES算法的工作密钥 Data也为 个字节 位 是要被加密或被解密的数据 Mode为DES的工作方式 有两种 加密或解密
DES算法是这样工作的 如Mode为加密 则用Key 去把数据Data进行加密 生成Data的密码形式( 位)作为DES的输出结果 如Mode为解密 则用Key去把密码形式的数据Data解密 还原为Data的明码形式( 位)作为DES的输出结果 在通信网络的两端 双方约定一致的Key 在通信的源点用Key对核心数据进行DES加密 然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点 数据到达目的地后 用同样的Key对密码数据进行解密 便再现了明码形式的核心数据 这样 便保证了核心数据(如PIN MAC等)在公共通信网中传输的安全性和可靠性
通过定期在通信网络的源端和目的端同时改用新的Key 便能更进一步提高数据的保密性 这正是现在金融交易网络的流行做法
DES算法详述
DES算法把 位的明文输入块变为 位的密文输出块 它所使用的密钥也是 位 其功能是把输入的 位数据块按位重新组合 并把输出分为L R 两部分 每部分各长 位 其置换规则见下表
即将输入的第 位换到第一位 第 位换到第 位 … 依此类推 最后一位是原来的第 位 L R 则是换位输出后的两部分 L 是输出的左 位 R 是右 位 例 设置换前的输入值为D D D ……D 则经过初始置换后的结果为 L =D …D ;R =D D …D
经过 次迭代运算后 得到L R 将此作为输入 进行逆置换 即得到密文输出 逆置换正好是初始置的逆运算 例如 第 位经过初始置换后 处于第 位 而通过逆置换 又将第 位换回到第 位 其逆置换规则如下表所示
放大换位表
单纯换位表
在f(Ri Ki)算法描述图中 S S …S 为选择函数 其功能是把 bit数据变为 bit数据 下面给出选择函数Si(i= …… )的功能表
选择函数Si
S :
S :
S :
S :
S :
S :
S :
S :
在此以S 为例说明其功能 我们可以看到 在S 中 共有 行数据 命名为 行 每行有 列 命名为 …… 列
现设输入为 D=D D D D D D
令 列=D D D D
行=D D
然后在S 表中查得对应的数 以 位二进制表示 此即为选择函数S 的输出 下面给出子密钥Ki( bit)的生成算法
从子密钥Ki的生成算法描述图中我们可以看到 初始Key值为 位 但DES算法规定 其中第 …… 位是奇偶校验位 不参与DES运算 故Key 实际可用位数便只有 位 即 经过缩小选择换位表 的变换后 Key 的位数由 位变成了 位 此 位分为C D 两部分 各 位 然后分别进行第 次循环左移 得到C D 将C ( 位) D ( 位)合并得到 位 再经过缩小选择换位 从而便得到了密钥K ( 位) 依此类推 便可得到K K …… K 不过需要注意的是 次循环左移对应的左移位数要依据下述规则进行
循环左移位数
以上介绍了DES算法的加密过程 DES算法的解密过程是一样的 区别仅仅在于第一次迭代时用子密钥K 第二次K …… 最后一次用K 算法本身并没有任何变化
DES算法具有极高安全性 到目前为止 除了用穷举搜索法对DES算法进行攻击外 还没有发现更有效的办法 而 位长的密钥的穷举空间为 这意味着如果一台计算机的速度是每一秒种检测一百万个密钥 则它搜索完全部密钥就需要将近 年的时间 可见 这是难以实现的 当然 随着科学技术的发展 当出现超高速计算机后 我们可考虑把DES密钥的长度再增长一些 以此来达到更高的保密程度
由上述DES算法介绍我们可以看到 DES算法中只用到 位密钥中的其中 位 而第 …… 位 个位并未参与DES运算 这一点 向我们提出了一个应用上的要求 即DES的安全性是基于除了 …… 位外的其余 位的组合变化 才得以保证的 因此 在实际应用中 我们应避开使用第 …… 位作为有效数据位 而使用其它的 位作为有效数据位 才能保证DES算法安全可靠地发挥作用 如果不了解这一点 把密钥Key的 …… 位作为有效数据使用 将不能保证DES加密数据的安全性 对运用DES来达到保密作用的系统产生数据被破译的危险 这正是DES算法在应用上的误区 是各级技术人员 各级领导在使用过程中应绝对避免的 而当今各金融部门及非金融部门 在运用DES工作 掌握DES工作密钥Key的领导 主管们 极易忽略 给使用中貌似安全的系统 留下了被人攻击 被人破译的极大隐患
DES算法应用误区的验证数据
笔者用Turbo C编写了DES算法程序 并在PC机上对上述的DES 算法的应用误区进行了骓 其验证数据如下
Key: x x x x …… x ( 个字节)
Data: x x x x …… x ( 个字节)
Mode: Encryption
结果 e a cf f
如果把上述的Key换为 个字节的 x 而Data和Mode均不变 则执行DES 后得到的密文完全一样 类似地 用Key: 个 x 和用Key: 个 x 去加密Data ( 个 x ) 二者的图文输出也是相同的 e c ac e b ba
我们可以得到出结论
Key用 x 与用 x 是一样的
Key用 x 与用 x 是一样的 ……
当Key由 个 x 换成 个 x 后 貌似换成了新的Key 但由于 x 和 x 仅仅是在第 …… 有变化 而DES算法并不使用Key的第 …… 位作为Key的有效数据位 故 加密出的结果是一样的
DES解密的验证数据
Key: x x …… x ( 个 x )
Data: e a cf f
Mode: Decryption
结果 x x …… x ( 个 x )
由以上看出 DES算法加密与解密均工作正确 唯一需要避免的是 在应用中 避开使用Key的第 …… 位作为有效数据位 从而便避开了DES 算法在应用中的误区
避开DES算法应用误区的具体操作
在DES密钥Key的使用 管理及密钥更换的过程中 应绝对避开DES 算法的应用误区 即 绝对不能把Key的第 …… 位作为有效数据位 来对Key 进行管理 这一点 特别推荐给金融银行界及非金融业界的领导及决策者们 尤其是负责管理密钥的人 要对此点予以高度重视 有的银行金融交易网络 利用定期更换DES密钥Key的办法来进一步提高系统的安全性和可靠性 如果忽略了上述应用误区 那麽 更换新密钥将是徒劳的 对金融交易网络的安全运行将是十分危险的 所以更换密钥一定要保证新Key与旧Key真正的不同 即除了第 … 位外其它位数据发生了变化 请务必对此保持高度重视!
* @author zy
*/
/**
* 本类实现的是基本数据类型上的算法运算
*/
public class DES
// 密钥
private String key;
// 为了字节数组与字符串互换而使用的
private static final String BASE _CHARS = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz* ;
private static final char[] BASE _CHARSET = BASE _CHARS toCharArray()
// 声明常量字节数组
/**
* DES算法把 位的明文输入块变为 位的密文输出块 它所使用的密钥也是 位 其功能是把输入的 位数据块按位重新组合
* 并把输出分为L R 两部分 每部分各长 位 其置换规则见下表 即将输入的第 位换到第一位 第 位换到第 位 … 依此类推
* 最后一位是原来的第 位 L R 则是换位输出后的两部分 L 是输出的左 位 R 是右 位
* 例 设置换前的输入值为D D D ……D 则经过初始置换后的结果为 L =D …D ;R =D D …D
*/
private static final int[] IP = // OK
; //
/**
* 经过 次迭代运算后 得到L R 将此作为输入 进行逆置换 即得到密文输出
* 逆置换正好是初始置的逆运算 例如 第 位经过初始置换后 处于第 位 而通过逆置换 又将第 位换回到第 位 其逆置换规则如下表所示
*/
private static final int[] IP_ = // OK
; //
/**
* PC 置换
*/
private static final int[] PC_ =
; //
/**
* PC 置换
*/
private static final int[] PC_ =
; //
/**
* 放大换位表
*/
private static final int[] E = // OK
; //
/**
* 单纯换位表
*/
private static final int[] P = // OK
; //
/**
* 在f(Ri Ki)算法描述图中 S S …S 为选择函数 其功能是把 bit数据变为 bit数据
* 下面给出选择函数Si(i= …… )的功能表 选择函数Si
*/
private static final int[][][] S_Box =
// S_Box[ ] OK
// S_Box[ ] OK
// S_Box[ ] OK
// S_Box[ ] OK
// S_Box[ ] OK
// S_Box[ ] OK
// S_Box[ ] OK
// S_Box[ ] OK
;
/**
* 循环左移位数
*/
private static final int[] LeftMove =
; // 左移位置列表
// 构造函数 初始化密钥
public DES(String key)
this key = key;
/**
*
* @param des_key
* 个字节的密钥字节数组
* @param des_data
* 个字节的数据字节数组
* @param flag
* 或 为加密 为解密
* @return 个字节的字节数组
*/
private byte[] UnitDes(byte[] des_key byte[] des_data int flag)
// 检测输入参数格式是否正确 错误直接返回空值(null)
if ((des_key length != ) || (des_data length != )
|| ((flag != ) && (flag != )))
throw new RuntimeException( Data Format Error ! )
int flags = flag;
// 二进制加密数据
int[] encryptdata = new int[ ];
// 加密操作完成后的字节数组
byte[] EncryptCode = new byte[ ];
encryptdata = ReadDataToBirnaryIntArray(des_data)
// 执行加密解密操作
EncryptCode = Encrypt(encryptdata flags KeyArray)
return EncryptCode;
/**
* 初试化密钥为二维密钥数组
*
* @param key
* int[ ]二进制的密钥数组
* @param keyarray
* new int[ ][ ]
*/
private void KeyInitialize(int[] key int[][] keyarray)
int i;
int j;
int[] K = new int[ ];
// 特别注意 xxx[IP[i] ]等类似变换
for (i = ; i < ; i++)
K [i] = key[PC_ [i] ]; // 密钥进行PC 变换
for (i = ; i < ; i++)
LeftBitMove(K LeftMove[i])
// 特别注意 xxx[IP[i] ]等类似变换
for (j = ; j < ; j++)
keyarray[i][j] = K [PC_ [j] ]; // 生成子密钥keyarray[i][j]
/**
* 执行加密解密操作
*
* @param timeData
* (int[ ])二进制加密数据
* @param flag
* 或 为加密 为解密
* @param keyarray
* new int[ ][ ]
* @return 长度为 的字节数组
*/
private byte[] Encrypt(int[] timeData int flag int[][] keyarray)
int i;
byte[] encrypt = new byte[ ];
int flags = flag;
int[] M = new int[ ];
int[] MIP_ = new int[ ];
// 特别注意 xxx[IP[i] ]等类似变换
for (i = ; i < ; i++)
M[i] = timeData[IP[i] ]; // 明文IP变换
if (flags == ) // 加密
for (i = ; i < ; i++)
LoopF(M i flags keyarray) // S盒处理
else if (flags == ) // 解密
for (i = ; i > ; i )
LoopF(M i flags keyarray) // S盒处理
for (i = ; i < ; i++)
MIP_ [i] = M[IP_ [i] ]; // 进行IP 运算
// 将(int[ ]二进制数据字节数组 经过IP S盒 IP 处理后 得到的新的)int[ ]二进制数据字节数组转换成byte[ ]的字节数组
GetEncryptResultOfByteArray(MIP_ encrypt)
// 返回加密数据
return encrypt;
/**
* 转换 个字节长度的数据字节数组为二进制数组 (一个字节转换为 个二进制)
*
* @param intdata
* 个字节的数据字节数组
* @return 长度为 的二进制数组
*/
private int[] ReadDataToBirnaryIntArray(byte[] intdata)
int i;
int j;
// 将数据转换为二进制数 存储到数组
int[] IntDa = new int[ ];
for (i = ; i < ; i++)
IntDa[i] = intdata[i];// intdata[i]为byte 范围是 ~
if (IntDa[i] < ) // 故 IntDa[i]范围是 ~
IntDa[i] += ;// IntDa[i]永远不会超过
IntDa[i] %= ;// 所以该处不需要取模 取模后结果还是自己
int[] IntVa = new int[ ];
for (i = ; i < ; i++)
for (j = ; j < ; j++)
IntVa[((i * ) + ) j] = IntDa[i] % ;
IntDa[i] = IntDa[i] / ;
return IntVa;
/**
* int[ ]二进制数据字节数组转换成byte[ ]的字节数组
*
* @param data
* int[ ]二进制数据字节数组
* @param value
* byte[ ] byte[ ]的字节数组
*/
private void GetEncryptResultOfByteArray(int[] data byte[] value)
int i;
int j;
// 将存储 位二进制数据的数组中的数据转换为八个整数(byte)
for (i = ; i < ; i++)
for (j = ; j < ; j++)
value[i] += (byte) (data[(i 《 ) + j] 《 ( j))
for (i = ; i < ; i++)
value[i] %= ;
if (value[i] > )
value[i] = ;
/**
* 左移
*
* @param k
* @param offset
*/
private void LeftBitMove(int[] k int offset)
int i;
// 循环移位操作函数
int[] c = new int[ ];
int[] d = new int[ ];
int[] c = new int[ ];
int[] d = new int[ ];
for (i = ; i < ; i++)
c [i] = k[i];
d [i] = k[i + ];
if (offset == )
for (i = ; i < ; i++) // 循环左移一位
c [i] = c [i + ];
d [i] = d [i + ];
c [ ] = c [ ];
d [ ] = d [ ];
else if (offset == )
for (i = ; i < ; i++) // 循环左移两位
c [i] = c [i + ];
d [i] = d [i + ];
c [ ] = c [ ];
d [ ] = d [ ];
c [ ] = c [ ];
d [ ] = d [ ];
for (i = ; i < ; i++)
k[i] = c [i];
k[i + ] = d [i];
/**
* S盒处理
*
* @param M
* @param times
* @param flag
* @param keyarray
*/
private void LoopF(int[] M int times int flag int[][] keyarray)
int i;
int j;
int[] L = new int[ ];
int[] R = new int[ ];
int[] L = new int[ ];
int[] R = new int[ ];
int[] RE = new int[ ];
int[][] S = new int[ ][ ];
int[] sBoxData = new int[ ];
int[] sValue = new int[ ];
int[] RP = new int[ ];
for (i = ; i < ; i++)
L [i] = M[i]; // 明文左侧的初始化
R [i] = M[i + ]; // 明文右侧的初始化
for (i = ; i < ; i++)
RE[i] = R [E[i] ]; // 经过E变换扩充 由 位变为 位
RE[i] = RE[i] + keyarray[times][i]; // 与KeyArray[times][i]按位作不进位加法运算
if (RE[i] == )
RE[i] = ;
for (i = ; i < ; i++) // 位分成 组
for (j = ; j < ; j++)
S[i][j] = RE[(i * ) + j];
// 下面经过S盒 得到 个数
sBoxData[i] = S_Box[i][(S[i][ ] 《 ) + S[i][ ]][(S[i][ ] 《 )
+ (S[i][ ] 《 ) + (S[i][ ] 《 ) + S[i][ ]];
// 个数变换输出二进制
for (j = ; j < ; j++)
sValue[((i * ) + ) j] = sBoxData[i] % ;
sBoxData[i] = sBoxData[i] / ;
for (i = ; i < ; i++)
RP[i] = sValue[P[i] ]; // 经过P变换
L [i] = R [i]; // 右边移到左边
R [i] = L [i] + RP[i];
if (R [i] == )
R [i] = ;
// 重新合成M 返回数组M
// 最后一次变换时 左右不进行互换 此处采用两次变换实现不变
if (((flag == ) && (times == )) || ((flag == ) && (times == )))
M[i] = R [i];
M[i + ] = L [i];
else
M[i] = L [i];
M[i + ] = R [i];
/**
* 把一个字节数组的元素拷贝到另一个字节数组中
*
* @param src
* @param srcPos
* @param dest
* @param destPos
* @param length
*/
private void arraycopy(byte[] src int srcPos byte[] dest int destPos
int length)
if (dest != null && src != null) // 当两个都不为空时
byte[] temp = new byte[length];
for (int i = ; i < length; i++)
temp[i] = src[srcPos + i];
for (int i = ; i < length; i++)
dest[destPos + i] = temp[i];
/**
* 格式化字节数组 使其的长度为 的倍数 那些不足的部分元素用 填充
*
* @return 一个新的字节数组 其长度比原数组长 位
*/
private byte[] ByteDataFormat(byte[] data)
int len = data length;
int padlen = (len % ) // 要格式化的字节数组的长度与 的倍数的差值
int newlen = len + padlen;
byte[] newdata = new byte[newlen];
arraycopy(data newdata len)
for (int i = len; i < newlen; i++)
newdata[i] = ;
return newdata;
/**
* 加密解密(主要方法)
*
* @param des_key
* 密钥字节数组
* @param des_data
* 要处理的数据字节数组
* @param flag
* ( 或 ) 为加密 为解密
* @return 处理后的数据
*/
private byte[] DesEncrypt(byte[] des_key byte[] des_data int flag)
byte[] format_key = ByteDataFormat(des_key) // 补齐密钥字节数组的长度为 的倍数 不足元素用 补
byte[] format_data = ByteDataFormat(des_data) // 补齐原始数据字节数组的长度为 的倍数 不足元素用 补
int datalen = format_data length;// 补齐后的原始数据字节数组的长度
int unitcount = datalen / ;// 补齐后的原始数据字节数组长度是 的多少倍
byte[] result_data = new byte[datalen];// 用于盛放加密后的结果
// Log v( unitcount unitcount + )
byte[] tmpkey = new byte[ ];// 真正起作用的密钥字节数组 只有 个字节
arraycopy(format_key tmpkey )
byte[] tmpdata = new byte[ ];// 用于参与操作的数据字节数组 只有 个字节
createKey(tmpkey)
// 每一次循环 都操作 个字节(加密解密)
for (int i = ; i < unitcount; i++)
// if (i % == )
// Log v( i i + )
arraycopy(format_data i * tmpdata )
byte[] tmpresult = UnitDes(tmpkey tmpdata flag) // 执行操作
arraycopy(tmpresult result_data i * )
return result_data;
// 密钥初试化成二维数组
int[][] KeyArray = new int[ ][ ];
private void createKey(byte[] des_key)
// 二进制加密密钥
int[] keydata = new int[ ];
// 将密钥字节数组转换成二进制字节数组
keydata = ReadDataToBirnaryIntArray(des_key)
// 初试化密钥为二维密钥数组
KeyInitialize(keydata KeyArray)
// 将加密数据字节数组转换成二进制字节数组
/**
* DES加密
*
* @param data
* 原始数据
* @return 加密后的数据字节数组
*/
public String encrypt(String data)
String dataLength = data length() + ;// 原始数据长度
String datal = dataLength;
// 原始数据长度不满 位的加 补满 位
for (int i = ; i < datal length() i++)
dataLength = + dataLength;
// System out println( dataLength = + dataLength)
String sbDate = dataLength + data;// 保证原始数据的前 位为该数据的长度
byte[] bytekey = key getBytes() // 密钥字节数组
byte[] bytedata = sbDate getBytes() // 原始数据字节数组
byte[] result = new byte[(bytedata length + ) (bytedata length % )];// 能包含原始数据字节数组的长度是 的倍数的最小字节数组
result = DesEncrypt(bytekey bytedata )
return toBase (result)
/**
* DES解密
*
* @param encryptData
* 加密后的数据字节数组
* @return 还原后的数据字符串
*/
public String decrypt(String encryptData)
try
byte[] encryptByteArray = fromBase (encryptData)
byte[] bytekey = key getBytes()
byte[] result = new byte[encryptByteArray length];
result = DesEncrypt(bytekey encryptByteArray )
String deResult = new String(result)
int dataLength = Integer parseInt(deResult substring( ))
return deResult substring( dataLength + )
catch (Exception e)
return ;
/**
* 字节数组转换为字符串
*
* @param buffer
* @return
*/
private String toBase (byte[] buffer)
int len = buffer length pos = len % ;
byte b = b = b = ;
switch (pos)
case :
b = buffer[ ];
break;
case :
b = buffer[ ];
b = buffer[ ];
break;
String returnValue = ;
int c;
boolean notleading = false;
do
// c = (b & xFC) >>> ;
c = (b & xFC) 》 ;
if (notleading || c != )
returnValue += BASE _CHARSET[c];
notleading = true;
// c = ((b & x ) 《 ) | ((b & xF ) >>> )
c = ((b & x ) 《 ) | ((b & xF ) 》 )
if (notleading || c != )
returnValue += BASE _CHARSET[c];
notleading = true;
// c = ((b & x F) 《 ) | ((b & xC ) >>> )
c = ((b & x F) 《 ) | ((b & xC ) 》 )
if (notleading || c != )
returnValue += BASE _CHARSET[c];
notleading = true;
c = b & x F;
if (notleading || c != )
returnValue += BASE _CHARSET[c];
notleading = true;
if (pos >= len)
break;
else
try
b = buffer[pos++];
b = buffer[pos++];
b = buffer[pos++];
catch (Exception x)
break;
while (true)
if (notleading)
return returnValue;
return ;
/**
* 字符串转换为字节数组
*
* @param str
* @return
* @throws Exception
*/
private byte[] fromBase (String str) throws Exception
int len = str length()
if (len == )
throw new Exception( Empty string )
byte[] a = new byte[len + ];
int i j;
for (i = ; i < len; i++)
try
a[i] = (byte) BASE _CHARS indexOf(str charAt(i))
catch (Exception x)
throw new Exception( Illegal character at # + i)
i = len ;
j = len;
try
while (true)
a[j] = a[i];
if ( i < )
break;
a[j] |= (a[i] & x ) 《 ;
j ;
// a[j] = (byte)((a[i] & x C) >>> )
a[j] = (byte) ((a[i] & x C) 》 )
if ( i < )
break;
a[j] |= (a[i] & x F) 《 ;
j ;
// a[j] = (byte)((a[i] & x ) >>> )
a[j] = (byte) ((a[i] & x ) 》 )
if ( i < )
break;
a[j] |= (a[i] 《 )
j ;
a[j] = ;
if ( i < )
break;
catch (Exception ignored)
try // ignore leading bytes
while (a[j] == )
j++;
catch (Exception x)
return new byte[ ]; // one byte
byte[] result = new byte[len j + ];
arraycopy(a j result len j + )
return result;
public byte[] eCode(byte[] bytes)
DesEncrypt(key getBytes() bytes )
return new byte [ ];
cha138/Article/program/Java/hx/201311/26705
相关参考
Java经典算法编程题目,适合面试前进行练习 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!定义一个
Java中3DES加密解密示例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在java中调用s
JAVA编程语言开发下载文件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! [java] /*
Java中3DES加密解密调用示例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在java中调
JAVA编程语言程序开发平方 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! [java] pa
现在的软件开发语言太多了尤其现在的所有软件都基本是B/S结构的所以对WEB开发语言的使用也就越来越多搞了几年的JAVA开发 这段时间也抽了点时间玩玩dotnetperlphp等其它WEB
JAVA编程语言程序开发技术Dijkstra 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Di
JAVADES加密解密实现 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! packagetxlt
针对Java开发人员的C#编程语言(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 此程序的
从Java语言编程谈软件开发流程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 你我的生活周遭已