发表于: 2018-05-20 19:00:01
1 1287
day51
今天完成的事情:
解决昨天的bug,主要是将密钥固定为一个值
在我之前的desUtil里,就有一个产生64位密钥的方法:
// 用于产生随机密钥时使用;
public static SecretKey gatRandomKey() {
SecretKey Skey = null;
try {
// 初始化密钥key
keyGenerator = KeyGenerator.getInstance(algorithm);
keyGenerator.init(56); // 选择DES算法,密钥长度必须为56位
Skey = keyGenerator.generateKey();
} catch (Exception ex) {
ex.printStackTrace();
}
return Skey;
}
里面的algorithm是我指定好的常量"DES", 代表用des加解密;keyGenerator.init(56) 指定生成56位密钥,加上它会拼接上的8位奇偶校验位,刚好64位。
调用上面的方法,返回一个SecretKey 类型的对象,SecretKey中有一个getEncoded()方法可以将密钥以字节数组返回,下面的代码通过Arrays.toString(keybytes),将字节打印出来
byte[] keybytes = gatRandomKey().getEncoded();
System.out.println(Arrays.toString(keybytes)); // [64, 115, -57, -48, 97, -32, -85, -62]
下面是将每个字节数字每个8bit元素以二进制字符串形式打印出来
byte[] keybytes = gatRandomKey().getEncoded();
StringBuffer sb = new StringBuffer();
System.out.println(Arrays.toString(keybytes)); // [64, 115, -57, -48, 97, -32, -85, -62]
for (int i = 0; i < keybytes.length; i++) {
sb.append(Integer.toBinaryString(keybytes[i])+",");
}
System.out.println(sb.toString());
Integer.toBinaryString(keybytes[i]),将字节以二进制字符串的形式输出
结果是这样的,由于每次产生密钥不同,所以首先打印出的八个整型有变了,这不是重点。打印出的二进制发现有的32位,有的6位,有的7位,原因是这样子的:
因为整型int本身占4个字节(32bit),负数的第8位必定为1(符号位),在转为整型int时,高24为1填充(因为负数以补码形式存在);
正数第8位必定是0,不以补码形式存在而以真实二进制值存在,高24为0填充,Integer.toBinaryString()在处理二进制转字符串时会把前面的0舍去
这些都是题外话,言归正传,将密钥转为8个字节时,为了便于存储和显示,将密钥以十六进制形式字符串展现。通过下面的方法转为16进制。
public static String bytesToHexFun1(byte[] bytes) {
char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
char[] buf = new char[bytes.length * 2];
int index = 0;
for(byte b : bytes) { // 利用位运算进行转换,可以看作方法一的变种
buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
buf[index++] = HEX_CHAR[b & 0xf];
}
return new String(buf);
}
得到这个字符串后,以常量形式存在工具类里,这样做到了密钥的存放。
private static Cipher cipher;
private static String algorithm = "DES"; // 算法,如DES
public static String strkey = "effed53d23fe5d76";
static KeyGenerator keyGenerator;
无论加密解密,即
cipher.init(Cipher.DECRYPT_MODE, key); 和
cipher.init(Cipher.ENCRYPT_MODE, key);
都要传入一个key,这里通过以下方法,将常量十六进制字符串转为密钥。这里用到了一个SecretKeySpec类,给入参字节数组和加密类型(DES) ,可以返回一个密钥,因为SecretKeySpec实现了SecretKey接口,我们用SecretKey来接它。有了这个静态方法,在加密解密需要密钥是只有调用它就好了。
// 用于产生固定密钥时使用;
public static SecretKey getConstantKey() {
SecretKey Skey = null;
Skey = new SecretKeySpec(HextoBytes(strkey),algorithm);
return Skey;
}
另外上面的实现有些细节,可以看到上面代码strkey是一个16进制字符串常量,需要转为字节数组,我们通过以下函数实现
//测试过关。
public static byte[] HextoBytes(String str) {
if(str == null || str.trim().equals("")) {
return new byte[0];
}
byte[] bytes = new byte[str.length() / 2];
for(int i = 0; i < str.length() / 2; i++) {
String subStr = str.substring(i * 2, i * 2 + 2);
bytes[i] = (byte) Integer.parseInt(subStr, 16);
}
return bytes;
}
里面的
Integer.parseInt(subStr, 16);
可以将字符串以16进制解析 转为整型,可以看到对 "effed53d23fe5d76"两位两位的拆分在转为int, 这种情况下会都是正数,高24位必定是0,剩下的只有8位,这样强转为byte类型是不会有比特丢失的,保证数据原本原的转为字节。如果是负数的话高24位中肯定会有1存在,这样强转会导致比特数据的丢失。
Git 的使用
一、将文件添加到暂存区,再提交到本地仓库
初始化一个本地版本库,执行一次即可,后面不用再执行
git init
设置用户名和邮箱(全局)
git config user.name "用户名"
这个位置
git config user.email "xxxxxx@qq.com"
就是github绑定邮箱
创建一个文件
touch ai.txt
查看状态
git status
将该文件添加到暂存区,然后再查看状态:
git add ai.txt
如下图示就是文件到了暂存区了
提交到本地版本库中
附:
1)-m后跟注释内容
2)可以 直接 在后面跟上文件,表示把该文件提交到本地版本库(不推荐)
3)不跟任何文件名称,表示把当前所有暂缓区中的内容都提交到 本地版本库 中
下面两种写法都可以,这里用的后一中
git commit -m "提交ai.txt文件试试" ai.txt
git commit -m "提交ai.txt文件试试"
出现如下代表提交成功
验证,nothing to commit, working tree clean表示成功将文件从暂存区提交到仓库
二、修改文件
先用vim命令对ai.txt文件进行修改,操作和在Liunx一模一样,修改完后在执行git status查看状态
这种红色的状态代表可提交(commit)
再次执行
git add ai.txt
这种绿色状态代表成功到达暂存区
然后执行commit,再查看状态nothing to commit, working tree clean
三、删除文件
step1: 删除本地
rm -rf ai.txt
step2:删除暂存区
git rm ai.txt
git statusstep3:提交删除
git commit -m "注释"
以上是从工作区到暂存区的操作,下面是操作远程仓库相关的
首先获得远程仓库地址
git config --list 查看设置过的参数
然后到一个你想放这些克隆文件的路径,可以是任何路径,右键点击 Git bash here
执行 git clone <刚才复制的地址>
整个repository就被下载下来了。
以下是进入文件夹,修改了一个文件,然后上传到暂存区,然后commit到本地仓库
那个 "测试用" 是个没有后缀名的文件,之前我已经用vim修改过了它的内容。
然后执行git push,上传到远程仓库
去自己github看了下,上传成功,也可以看到自己注释的信息等等。
参考:https://blog.csdn.net/yeshaojian/article/details/51317297
总结:
touch xx.txt 创建文件
git add xx.txt 添加到缓存区
git commit -m "hahaha" 提交到本地仓库
git push 上传到远程仓库
用git命令提交代码
先在gitHub上创建一个仓库
回到本地,在你要操作的项目文件夹下,鼠标右击打开 git bash命令窗口
如果项目文件夹里没有.git的隐藏文件,先执行git init,将此文件夹变为git可以管理的仓库
通过git add . 将所有文件提交,点代表当前路径下所有文件
上面的操作就将当前路径下所有文件放到了暂存区
通过git status可以看到文件都变绿色代表是在暂存区可提交的状态
git commit -m "注释" ; 将文件从暂存区提交到本地仓库
这个时候本地的仓库和没有和远程发生关联
通过 git remote add origin https://github.com/LittleSong2313996874/Task5.git,
git remote是管理远程仓库的命令,后面的add origin <地址> ,表示增加了一个origin远程仓库,origin是一个指针指向了后面的value。
在将本地仓库与GitHub网站上的仓库进行关联后,便可进行推送了,但是在第一次进行推送时,需要注意的是,GitHub网站上的仓库并非是空的,在创建时创建了一个README文档,因此需要将两者进行合并才行。rebase和merge都代表合并,两者区别:rebase和bersge区别
git pull --rebase origin master
最后,再进行推送即可。
git push -u origin master
这个带有-u这个参数是指,将master分支的所有内容都提交,第一次关联之后后边你再提交就可以不用这个参数了,之后你的每一次修改,你就可以只将你修改push就好了。
git push origin master
去刷新github发现提交成功。
上述命令中,origin代表远程仓库,master代表其分支。
比如:
git push A B:C 其中A和C是分别remote端的一个repository的名字和其branch的名字,B是本地端branch的名字
它的意思是把本地的B推送到remotes/A/C下。当B=C时可以直接省略为:git push A B。比如:
"git push origin master:master" 可以直接省略为"git push origin master".
再比如:
git push origin master //把本地仓库提交到远程仓库的master分支中
$ git push origin test:master // 提交本地test分支作为远程的master分支
$ git push origin test:test // 提交本地test分支作为远程的test分支
链接:
git一些概念理解
origin 多用于指代远程仓库
master 多用于指定分支,可以是远程端分支也可以是本地端
fetch 拿取 push 推送
git branch -a 查看所有分支
上面的显示表示
master 代表本地分支,
origin/master是远程分支 (origin指向仓库,master指向分支)
第一行的master前面的星号是你所在的分支的标记
第二行的红色是因为我后来对远程仓库master分支做了修改,本地和远程不同步。
另外关于 git clone remote branch等等一些命令概念讲解,推荐这个链接 : git clone,push,remote,fetch命令详解
https://github.com/LittleSong2313996874/Task5.git
https://github.com/LittleSong2313996874/Task5.git
https://github.com/LittleSong2313996874/Task5.git
https://github.com/LittleSong2313996874/Task5.git
https://github.com/LittleSong2313996874/Task5.git
明天计划的事情:
学习Jmete
遇到的问题:
暂无
收获:
学习git命令
评论