1、文件拷贝,把一个文件的内容拷贝到另外一个文件里
package order;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileInputOutputStreamTest {
public static void mainString[] args) {
File af = new File"F:/srv/workspace/test/src/a.txt");
File bf = new File"F:/srv/workspace/test/src/b.txt");
FileInputStream is = null;
FileOutputStream os = null;
if!bf.exists)){
try {
bf.createNewFile);
} catch IOException e) {
e.printStackTrace);
}
}
try {
is = new FileInputStreamaf);
os = new FileOutputStreambf);
byte b[] = new byte[1024];
int len;
try {
len = is.readb);
while len != -1) {
os.writeb, 0, len);
len = is.readb);
}
} catch IOException e) {
e.printStackTrace);
}
} catch FileNotFoundException e) {
e.printStackTrace);
}finally{
try {
ifis != null) is.close);
ifos != null) os.close);
} catch IOException e) {
e.printStackTrace);
}
}
}
}
————————————————————————————————————————————————————————————————————————————
2、jsp里边的对象,以及常用的方法
————————————————————————————————————————————————————————————————————————————
内置对象特点:
1. 由JSP规范提供,不用编写者实例化。
2. 通过Web容器实现和管理
3. 所有JSP页面均可使用
4. 只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%>或<%使用内置对象%>)
常用内置对象:
1. 输出输入对象:request对象、response对象、out对象
2. 通信控制对象:pageContext对象、session对象、application对象
3. Servlet对象:page对象、config对象
4. 错误处理对象:exception对象
对象常用方法说明:
1.out对象(数据流 javax.servlet.jsp.jspWriter)
方法名 |
说明 |
print或println |
输出数据 |
newLine |
输出换行字符 |
flush |
输出缓冲区数据 |
close |
关闭输出流 |
clear |
清除缓冲区中数据,但不输出到客户端 |
clearBuffer |
清除缓冲区中数据,输出到客户端 |
getBufferSize |
获得缓冲区大小 |
getRemaining |
获得缓冲区中没有被占用的空间 |
isAutoFlush |
是否为自动输出 |
2.request对象(请求信息 javax.servlet.http.HttpServletrequest)
方法名 |
说明 |
isUserInRole |
判断认证后的用户是否属于某一成员组 |
getAttribute |
获取指定属性的值,如该属性值不存在返回Null |
getAttributeNames |
获取所有属性名的集合 |
getCookies |
获取所有Cookie对象 |
getCharacterEncoding |
获取请求的字符编码方式 |
getContentLength |
返回请求正文的长度,如不确定返回-1 |
getHeader |
获取指定名字报头值 |
getHeaders |
获取指定名字报头的所有值,一个枚举 |
getHeaderNames |
获取所有报头的名字,一个枚举 |
getInputStream |
返回请求输入流,获取请求中的数据 |
getMethod |
获取客户端向服务器端传送数据的方法 |
getParameter |
获取指定名字参数值 |
getParameterNames |
获取所有参数的名字,一个枚举 |
getParameterValues |
获取指定名字参数的所有值 |
getProtocol |
获取客户端向服务器端传送数据的协议名称 |
getQueryString |
获取以get方法向服务器传送的查询字符串 |
getRequestURI |
获取发出请求字符串的URI标识不含协议,主机,端口和参数) |
getRequestURL |
获取客户端请求的URL地址 |
getRemoteAddr |
获取客户端的IP地址 |
getRemoteHost |
获取客户端的名字 |
getSession |
获取和请求相关的会话 |
getServerName |
获取服务器的名字 |
getServerPath |
获取客户端请求文件的路径 |
getServerPort |
获取服务器的端口号 |
removeAttribute |
删除请求中的一个属性 |
setAttribute |
设置指定名字参数值 |
setCharacterEncoding |
设置请求的字符编码方式 |
3.response对象(响应 javax.servlet.http.HttpServletResponse)
方法名 |
说明 |
addCookie |
添加一个Cookie对象 |
addHeader |
添加Http文件指定名字头信息 |
containsHeader |
判断指定名字Http文件头信息是否存在 |
encodeURL |
使用sessionid封装URL |
flushBuffer |
强制把当前缓冲区内容发送到客户端 |
getBufferSize |
返回缓冲区大小 |
getCharacterEncoding |
获取响应的字符编码方式 |
getOutputStream |
返回到客户端的输出流对象 |
sendError |
向客户端发送错误信息 |
sendRedirect |
把响应发送到另一个位置进行处理 |
setContentType |
设置响应的MIME类型 |
setCharacterEncoding |
设置响应的字符编码方式 |
setHeader |
设置指定名字的Http文件头信息 |
4.session对象(会话 javax.servlet.http.HttpSession)
方法名 |
说明 |
getAttribute |
获取指定名字的属性 |
getAttributeNames |
获取session中全部属性名字,一个枚举 |
getCreationTime |
返回session的创建时间 |
getId |
获取会话标识符 |
getLastAccessedTime |
返回最后发送请求的时间 |
getMaxInactiveInterval |
返回session对象的生存时间单位千分之一秒 |
invalidate |
销毁session对象 |
isNew |
每个请求是否会产生新的session对象 |
removeAttribute |
删除指定名字的属性 |
setAttribute |
设定指定名字的属性值 |
5.pageContext对象(页面上下文 javax.servlet.jsp.PageContext)
方法名 |
说明 |
forward |
重定向到另一页面或Servlet组件 |
getAttribute |
获取某范围中指定名字的属性值 |
findAttribute |
按范围搜索指定名字的属性 |
removeAttribute |
删除某范围中指定名字的属性 |
setAttribute |
设定某范围中指定名字的属性值 |
getException |
返回当前异常对象 |
getRequest |
返回当前请求对象 |
getResponse |
返回当前响应对象 |
getServletConfig |
返回当前页面的ServletConfig对象 |
getServletContext |
返回所有页面共享的ServletContext对象 |
getSession |
返回当前页面的会话对象 |
6.application对象(应用程序 javax.servlet.ServletContext)
方法名 |
说明 |
getAttribute |
获取应用对象中指定名字的属性值 |
getAttributeNames |
获取应用对象中所有属性的名字,一个枚举 |
getInitParameter |
返回应用对象中指定名字的初始参数值 |
getServletInfo |
返回Servlet编译器中当前版本信息 |
setAttribute |
设置应用对象中指定名字的属性值 |
removeAttribute |
删除属性,根据键/值来删除application中所存放的对象值 |
7.config对象(Servlet的配置信息 javax.servlet.ServletConfig)
方法名 |
说明 |
getServletContext |
返回所执行的Servlet的环境对象 |
getServletName |
返回所执行的Servlet的名字 |
getInitParameter |
返回指定名字的初始参数值 |
getInitParameterNames |
返回该JSP中所有的初始参数名,一个枚举 |
8.page对象(当前JSP的实例,java.lang.object)
它代表JSP被编译成Servlet,可以使用它来调用Servlet类中所定义的方法
9.exception对象(运行时的异常,java.lang.Throwable)
被调用的错误页面的结果,只有在错误页面中才可使用,
即在页面指令中设置:<%@page isErrorPage=“true”%>
Request(Javax.servlet.ServletRequest)它包含了有关浏览器请求的信息.通过该对象可以获得请求中的头信息、Cookie和请求参数。
Response(Javax.servlet.ServletResponse)作为JSP页面处理结果返回给用户的响应存储在该对象中。并提供了设置响应内容、响应头以及重定向的方法(如cookies,头信息等)
Out(Javax.servlet.jsp.JspWriter)用于将内容写入JSP页面实例的输出流中,提供了几个方法使你能用于向浏览器回送输出结果。
pageContext(Javax.servlet.jsp.PageContext)描述了当前JSP页面的运行环境。可以返回JSP页面的其他隐式对象及其属性的访问,另外,它还实现将控制权从当前页面传输至其他页面的方法。
Session(javax.servlet.http.HttpSession)会话对象存储有关此会话的信息,也可以将属性赋给一个会话,每个属性都有名称和值。会话对象主要用于存储和检索属性值。
Application(javax.servle.ServletContext)存储了运行JSP页面的servlet以及在同一应用程序中的任何Web组件的上下文信息。
Page(Java.lang.Object)表示当前JSP页面的servlet实例
Config(javax.servlet.ServletConfig)该对象用于存取servlet实例的初始化参数。
Exception(Javax.lang.Throwable)在某个页面抛出异常时,将转发至JSP错误页面,提供此对象是为了在JSP中处理错误。只有在错误页面中才可使用
————————————————————————————————————————————————————————————————————————————
3、HashMap遍历的几种方法
————————————————————————————————————————————————————————————————————————————
第一种:
Map map = new HashMap);
Iterator iter = map.entrySet).iterator);
while iter.hasNext)) {
Map.Entry entry = Map.Entry) iter.next);
Object key = entry.getKey);
Object val = entry.getValue);
}
效率高,以后一定要使用此种方式!
第二种:
Map map = new HashMap);
Iterator iter = map.keySet).iterator);
while iter.hasNext)) {
Object key = iter.next);
Object val = map.getkey);
}
效率低,以后尽量少使用!
————————————————————————————————————————————————————————————————————————————
4、写一个类,连接数据库并执行一条sql
————————————————————————————————————————————————————————————————————————————
public class Student{//主方法private String name ;private String id;public StudentString name,String id){this.name=name;this.id=id;} package ch03;import java.sql.Connection;
import java.sql.DriverManager;public class JDBConnection {private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";private static final String DATABASE_URL = "jdbc:mysql://localhost:8080;databaseName=student";private static final String DATABASE_USER = "localhost";private static final String DATABASE_PASSWORD = "123456";private Connection con = null;public Connection getConnection) {try {Class.forNameDRIVER_CLASS);con=DriverManager.getConnectionDATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);System.out.println"连接成功!");} catch Exception ex) {System.out.println"2:"+ex.getMessage));}return con;}
}
需要一个名字是student的数据库 用户名localhost 密码123456
二、SQL
Structur query language
结构化查询语言,是操作关系型数据库中的对象。
DDL(Data definition language 数据定义语言),用于建表或删表操作,以及对表约束进行修改
create table , alter table , drop table 对表结构的增删操作。
DML(Data manipulation language 数据操作语言),向表中插入纪录,修改纪录
insert , update , delete , merge
transaction ,事务控制语言,由DML语句组成的,commit; ,rollback;
select 查询语句
dcl 授权语句 grant
三、Oracle
DBMS 数据库管理系统
有Oracle提供,还提供AS,应用服务器
DBA 数据库管理员
四、相关操作
1、sqlplus 访问数据库命令(本地访问/远程访问),和数据库建立连接的命令,是数据库操作的环境
sqlplus 用户名/密码
2、show user 显示当前用户的用户名
改变身份可以直接connect 用户名/密码 — 这个是sqlplus命令
在sqlplus中可以使用 ! 可以在shell和sqlplus间切换,!shell命令 可以在sqlplus中使用shell命令。
实际上是sqlplus开了子进程来执行shell命令。
3、Oracle数据库中的表分两类:用户表(用户使用操作的表),系统表(数据库系统维护的表,也叫数据字典)
对用户表的DDL操作出发了对系统表的DML操作!
五、基本语法
1、select查询语句
select table_name from user_tables;(查询系统表)
以上的查询语句就是查询本用户下所拥有的所有表的表名。
投影操作,只查看选择的字段的信息。
选择操作,查看字段中的特定某些信息。
联接操作,多表查询,通过表间连接,查寻出多表中的信息
(1)select table_name from user_tables;(查询系统表)
以上的查询语句就是查询本用户下所拥有的所有表的表名。
(2)sqlplus的buffer中会缓存最后一条sql语句,可以使用"/"来执行这最后一条sql语句,也可以使用
edit命令来编辑最后一条sql语句。
l命令(list)(sqlplus命令)可以显示buffer中最后一条命令。
sqlplus命令可以缩写
(3)desc [表名]
这是一条sqlplus命令,注意他不是sql语句,这条命令用于查看表的结构。descript的缩写
[字段名] [字段的类型],这是使用完desc命令后显示的表结构。
(4)select [表的字段名1],[表的字段名2], … from 表名;
select * from 表名; 查寻表中所有字段的信息
(5)关键字不等拆分,sql语句,以及表名,字段名是大小写不敏感的。
sql语句要以";"结尾,来表示sql语句结束,如果不加";"系统不会执行此条sql语句,并提示。
在Oracle中字符显示是左对齐,数值右对齐。
(6)在select 语句中可以使用数学表达式。
select [表达式(必须包含本表字段名)],[…],…. from 表名;
运算的优先级的先乘除后加减,同级自左向右运算,括号改变优先级。
(7)别名
select [字段名或表达式] ["别名"],[…] ["…"],…. from 表名;
可以通过在字段名或表达式后加空格"别名",可以给列,或者表达式结果其别名。
表达别名必须加双引号。
(8)字符串拼接使用||符号
select 目标字段名||" "||目标字段名 from 表名;
注意:在Oracle中的字符串要用'..'包含
别名中需要使用空格,或是大小写敏感时需要用".."包含。
练习:
自己写一条SQL语句,执行的结果是select * from …;
其中…是每张系统表的表名
即在每张系统表的表名前加“select * from” ,后加“;”
select 'select * from '||table_name||';' from user_tables;
2、处理错误
(1)!oerr ora [错误号] ,系统可以显示错误的原因和如何修改。如果命令错误输入可以使用edit或ed来修改输入错误。
实际上是在编辑缓存文件中的最后一条sql语句。
也可以使用 change) c /错误字段/正确字段,来进行替换操作进行修改。
只有在Linux平台使用
! 相当于 host ,没有断连接,只是切换了一下,执行shell命令
(2)edit命令来编辑最后一条sql语句。
3、sqlplus设置
set pause on 回车响应,分屏显示,只在本会话中有效
set pause off 关闭分屏显示。
set pause "…" 设置分屏显示的提示信息。
set pause on 先输出提示信息,回车响应,分屏显示
set head off 提头输出关闭
set feed off 结尾输出关闭
set echo off 回写关闭
spool 文件名.sql 写入指定文件
spool off 关闭写入。
4、sql脚本
也就是在文件中写有sql语句的文件,可以在sqlplus中运行。
引入sql脚本
sqlplus 用户名/密码 @sql脚本 (注意:在用户名密码输入结束后一定要加空格然后再写@sql脚本)
在脚本中最后一行写上“exit”,则运行完脚本以后,回到shell上
5、
Oracle中的空值 空值会当无穷大处理,其实空值根本就不会存储,只是看作是无穷大。
Oracle中控制处理函数 NVL字段名,值),这个字段中的空值替换为指定值,如果不为空,则会返回其原值。
例:select salary*12)*NVLcommission_pct,0)/100+1) salary,first_name from s_emp;
distinct关键字,去掉重复行(这个关键字会触发排序操作)
例: select distinct dept_id,title from s_emp;
dept_id与title的联合不唯一
注意:distinct,关键字之后会对from之前的字段进行排重操作。
6、column命令 — sqlplus命令
column命令 列格式的定义
column 目标列名 查看这个类是否定义了格式
column 目标列名 format a.. 设置列宽。
column last_name heading 'Employee|Name' FORMAT A15
设置题头
这其中的'|'是换行符
column salary justify left format $99,990.00
定义数字显示格式
注意:如果不满足显示的格式,就会把数据显示为"#"
column salary justify left format $00,000.00
会出现$00,928.00 ,用0补齐
column 列名 clear (清除列格式定义)
注意:只有sqlplus命令才有简写,并且在使用sqlplus命令时结尾也不能加分号。
六、选择操作
1、order by
排序子句 ASC(默认,升序) DESC(降序)
order by 目标列名(别名) 排序顺序(不写排序顺序,会默认为升序排序)
例:select first_name from s_emp order by first_name;
select first_name from s_emp order by first_name desc;
注意:升序空值在结果的末尾,降序空值在结果的最前面。
2、where子句
where子句使用在 select … from … 后面,用来选择所需(符合条件的)的记录
where后面跟的是表达式 也就是 XXX=XXX, XXX between X and X ,XXX in(X,X,X)
like '…' 通配查询
between … and … ,表示结果在这之间,between and是一个闭区间,
也就相当于… <= … and … >= … 。
!=,<>,^=,这三个都标识不等于,<=,>=,=,这些运算符都可以使用。
… in va1,val2,…) 判断结果是否在这个枚举中存在
like '…' 字符串通配查询,'%'表示多个字符,'_',表示一个字符。
注意:转义的用法:like ‘S\_%’ escape ‘\’
… and … 表示只有两个条件同时满足
… or … 表示条件只要满足其中只一就可以
all … 是要求都满足条件。
not …..,则是可以与以上的条件产生反效果。
空值会对not in造成影响,也就是不等于任何值,但是空值例外。
… is null 使用来判断值是否为空。
注意:Oracle中的字符串是严格区分大小写的。
(1)注意数据类型,数字类型直接写,字符用'……' ,缺省格式的Date可以用'……',只有别名
才用" "包含。
(2)选择合适的运算符
七、单行函数
1.字符函数
字符是大小写敏感的
转小写 lower字段名) — 其中的参数可以是一个字符串常量或是一个字段名
转大写 upper字段名)
首字母大写 initcap字段名)
字符串拼接 concat字段1, 字段2)
截取子串 substr字段名, 起始位置,取字符个数)
dual表,是专门用于函数测试和运算的,他只有一条记录
字符串拼接 concat…,….)
求指定子串 substr…,起始位置,取字符个数)
可以使用"-"表示从右向左取,取的时候可以从左往友取。
例:select substrfirst_name,-2,2) sub from s_emp;(取后两个)
select substrfirst_name,2,2) sub from s_emp;(取前两个)
2,数值函数
四舍五入 round数据,保留小数点后几位)
可以用负数表示小数点前,0,表示小数点后第一位,也就是保留个位,-1表示个位(保留到十 位)。
例:select round15.36,1) from dual;
截取数字函数 trunc数据,保留的位数(小数点后位数)) 截取个位之后补0
例:select trunc123.456,1) from dual;
3,日期函数
日期格式,
全日期格式 世纪信息,年月日,时分秒。
缺省日期格式,日-月-年 dd-mon-rr
修改当前会话的日期格式,会按照指定的格式输出日期
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
返回当前日期 sysdate
例:select sysdate from dual;
select sysdate+1 from dual; 获得明天的日期,加1,单位是天
日期是格式敏感的
求两个日期间相隔了多少个月 months_betweendate1,date2)
加减指定数量的月份 add_monthsdate,月数),月数可以为负,负值就是减去相应的月数。
从date日期开始的第一个星期五 next_daydate,FriDay)
返回月末的日期 last_daydate)
截取日期 truncdate,'年或月或日或时分秒')
例:select next_daysysdate,2) from dual;
例:select truncadd_monthssysdate,1),'month') from dual;
ROUND'25-MAY-95','MONTH') 01-JUN-95
ROUND'25-MAY-95 ','YEAR') 01-JAN-95
TRUNC'25-MAY-95 ','MONTH') 01-MAY-95
TRUNC'25-MAY-95 ','YEAR') 01-JAN-95
练习:
返回下个月的第一天的日期
select roundlast_daysysdate),'MONTH') from dual;
select add_monthstruncsysdate,'MONTH'),1);
4,不同数据类型间转换函数
将日期转成字符 tochardate,'日期格式')
日期格式要用有效格式,格式大小写敏感 'yyyy mm dd hh24:mi:ss',
'year'全拼的年),'mm'数字表示的月) 'month'全拼的月),'day'星期的全拼),'ddspth' 日期的全拼) 'yy mm dd'
例:select to_charsysdate,'yyyy mm dd hh24:mi:ss')from dual;
将字符转换成数字 to_number'…')
将数字转字符to_charnumber,'fmt') fmt是数字格式
将字符串转成日期 to_date'…','日期格式')
例:select to_charto_date'2006 11 03','yyyy mm dd'),'dd-month-yy') from dual;
1、等值连接
select [表别名1.字段名1],[表别名2.字段名2],…
from 表1 表别名1 ,表2 表别名2
where 表别名1.字段名3=表别名2.字段名4;
表连接时,当表与表之间有同名字段时,可以加上表名或表的别名,加以区分,使用时要用
表名.字段名或表别名.字段名(列名)。当表的字段名是唯一时,可以不用加上表名或表的别名。
注意:当为表起了别名,就不能再使用表名.字段名。
例:select a.first_name,a.last_name,b.name
from s_emp a,s_dept b
where a.dept_id=b.id;
2、非等值连接
select [表别名1.字段名1],[表别名2.字段名2],…
from 表1 表别名1 ,表2 表别名2
where 表别名1.字段名3 ….. 表别名2.字段名4
….可以使比较运算符,也可以使其他的除了'='的运算符
例:select e.ename, d.grade,e.sal
from emp e,salgrade d
where e.sal between d.losal and d.hisal;
3、自连接
用别名把一张表中的数据分成两部分,然后在使用条件过滤。
select [表别名1.字段名1],[表别名2.字段名2],…
from 表1 表别名1 ,表1 表别名2
where 表别名1.字段名3=表别名2.字段名4;
例:select a.first_name ename,b.first_name cname
from s_emp a,s_emp b
where a.manager_id=b.id;
以上所提到的表连接,都叫做内连接,严格匹配两表的记录。
4、外连接
会使用一方表中的所有记录去和另一格表中的记录按条件匹配,空值也会匹配,这个表中的所有记录都会显示,数据库会模拟出记录去和那些不匹配的记录匹配。
例:select a.first_name enamei,a.id,b.first_name cname,b.id
from s_emp a,s_emp b
where a.manager_id=b.id+);
即用a表中的数据去匹配b表的,若b表中有null,系统模拟纪录与其匹配
注意:要把那一方的记录全部都显示出来,还有注意条件+)跟在要全部选出的对端。
外连接的应用:
列出哪个部门没有员工
select e.deptno,d.deptno
from emp e,dept d
where e.deptno+)=d.deptno
and e.deptno is null;
三、组函数
group 组
group by 分组子句,按指定的分组规则分组 ,这个group by 子句可以跟在 select 语句后或是 having后面。
group by子句也会出发排序操作,会按分组字段排序。
select [组函数或分组的字段名] ,… from 表名 group by [字段名1],[字段名2],…..;
例:select avgsalary) from s_emp group by dept_id;
注意:组函数可以处理一组数据,返回一个值。
组函数会忽略空值。
avg..),求平均值,sum..),求和 这两个函数的参数只能是number型的。
以下所提到的函数可以使用任意类型做参数。
count..),用来统计记录数,可以使用排重命令。count…)默认使用的是all。
max..),min..)求最大值和最小值,
count*),统计表中记录数。
例:select maxb.name),avga.salary), maxc.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.dept_id;
注意:只要写了group by子句,
*** select后就只能用group by后的字段或者是组函数。 ***
where子句只能够过滤记录,放单行函数。
having子句可以过滤组函数结果或是分组的信息,且写在group by子句后。
例:
select maxb.name),avga.salary), maxc.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.id
having suma.salary)>4000;
column 也可以定义有别名的列的格式。
column "别名" 格式定义
注意:要先过滤掉不需要的记录,然后再进行分组操作,提高效率。
四、子查询
子查询,就是可以嵌在任何的sql语句中的select语句。
在select语句中嵌套子查询时,会先执行子查询。一般的会将子查询放在运算符的右边。
注意:在使用子查询时,要注意这个运算符是单行的(也就是只能是单值),还是多行运算符(范围,多值,in)。
配合使用子查询返回的结果必须符合运算符的用法。
例:
select first_name,title
from s_emp
where title=anyselect title from s_emp
where last_name='Smith')
and upperlast_name)!='SMITH';
select first_name,title
from s_emp
where title in select title from s_emp
where last_name='Smith')
and upperlast_name)!='SMITH';
五、将业务需求转换成可操作的表
一: 需求分析
二: 画E-R图
三: 转换成表关系
四: 割接(新老系统交接)
五:
E-R图属性:
* 为强制且非空属性
o 可选属性可以有值也可以没有)
#* 表示此属性唯一且非空
实体关系:
mastbean maybean
数量关系: 多对一关系
一对多关系
一对一关系
多对多关系
第一范式,所有的属性都必须是单值,也就是属性只表示单一的意义。(记录可以重复,没有任何限制)
第二范式,属性要求唯一且非空,(记录不可重复,但是数据可能会出现冗余)。
第三范式,非主属性只能依赖于主属性,不能依赖于其他非主属性。(解决数据冗余问题)
六、约束
约束是针对表中的字段进行定义的。
primary key (主键约束 PK)保证实体的完整性,保证记录的唯一
主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为主键,只有两个字段放在一起唯一标识记录,叫做联合主键。
foreign key (外建约束 FK)保证引用的完整性,
外键约束,外键的取值是受另外一张表中的主键或唯一值得约束,不能够取其他值,只能够引用主键会唯一键的值,被引用的表,叫做parent table(父表),引用方的表叫做child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入也是如此,先父表后子表,删除记录,要先删除子表记录,后删除父表记录,要修改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,后删除父表。
unuque key(唯一键),值为唯一
index(索引)是数据库特有的一类对象,view(示图)
典型的一对多 class 对应多个学生。
student table class table
______________________________ _________________________
| id | name | address| class_id| | id |class_desc|class_num|
|PK)|______|________|___FK)__| |pk)|__________|_________|
| | | | | | | | |
一对一
student tabel shenfenzheng table
____________________ _________________________________
| id | name | address| | s_id |shenfen_desc|shenfen_num|
|PK)|______|________| |PK,FK)|____________|___________|
| | | | | | | |
多对多
student tabel zhongjian table kecheng table
____________________ _________________________________ __________________
| id | name | address| | s_id |shenfen_desc|shenfen_num| | kid | kechengname|
|PK)|______|________| |FK,FK)|____________|___________| | PK)|____________|
| | | | |联合主键| | | | | |
引用对方表的主键,当作本身的主键,所以这个表的主键,既是主键又是外建
建表和其他相关操作
DDL语句
创建表:
create table 表名 字段名1 类型数据长度)default …) 约束条件, 字段名2 类型数据长度) 约束条件 );
Oracle数据库中的数据类型
varchar长度),可变长字符串,char长度) 定长
number..,..),number 表示浮点数,或者是整数
long 大对象,clog 字符的大对象,相当于文本文件在表中只存放一个相当于只针对值
blog 二进制的大对象,也是以相当于指针的形式存放的。
primary key约束:
主键约束的定义:
第一种定义形式:
create table testc number primary key ); 列级约束
第二种定义形式:
create table testc number , primary keyc) ) ; 表级约束
create table test c1 number constraints pkc1 primary key ); 此约束有名字: pkc1
create table testc number , c2 number , primary key c ,c1) ) ; 用表级约束可以实现联合主键
foregin key fk) 外键约束:
先定义父表,再定义子表)
carete table parentc1 number primary key );
create table child c number primary key , c2 number references parentc1));
或表级约束定义:
create table child c number primary key , c2 number , foreign keyc2) references parentc1));
如果两个字段都为唯一且非空,这时可以定义成UK+NOT NULL
PK或UK)一对多FK)
PK+UK)一对一FK) 或 PK)一对一PK)
多对对多关系,一般都通过一张中间表来分解成两个一对多的表
建立表
create table[schema]table
schema: 一个用户对应一个schema 不同用户下的表不能互相查看
select count*) from s_dept; <===> select count*) from sd0611.s_dept;
一个表中只能存储一个LONG类型
CLOB 存储大的文本对象
BLOB 存储大的二进制对象
create table testc1 number primary key); 设置主键
create table testc1 number constraints test_c1 primary key); 定义约束名,默认约束名为SYS_ 在列后面定义约束称为列级约束
create table testc1 number primary keyc1)); 所有列定义完后再定义约束称为表级约束能定义联合主键)
cretae table testc1 number,c2 number,priary keyc1,c2)); 定义联合主键
create table childc1 number primary key); 先要定义父表
create table childc1 number primary key, c2 number references parentc1)); 然后定义子表 references parent定义外键
create table childc1 number primary key, c2 number references parentc1) on delete cascate); on delete cascate为级联删除
create table childc1 number primary key, c2 number references parentc1) on delete set null); on delete set null删除后将外键置空
create table child c1 number primary key, c2 number,foreignkeyc2) references parentc1));
二、约束
1、非空约束(not null)
这是一个列级约束
在建表时,在数据类型的后面加上 not null ,也就是在插入时不允许插入空值。
例:create table studentid number primary key,name varchar232) not null,address varchar232));
2、unique 唯一约束
唯一约束,是会忽略空值的,唯一约束,要求插入的记录中的值是为一的。
例:create table studentid number,name varchar232),address varchar232),primary key id),unique address));
如果创建一个uk,系统自动建一个唯一索引
3、pk、uk
Oralce支持级联删除,不支持级联更新
4、check约束
检查约束,可以按照指定条件,检查记录的插入。check中不能使用尾列,不能使用函数,不能引用其他字段。
例:create table sal a1 number , checka1>1000));
连接实例:
package com.jdbc;
import java.sql.Connection; //代表对特定数据库的连接
import java.sql.DriverManager; //处理数据的调入并且对产生新的数据库连接提供支持
import java.sql.ResultSet; //控制执行查询语句得到的结果集
import java.sql.SQLException;
import java.sql.Statement; //代表一个特定的容器,容纳并执行一条SQL语句
public class JdbcText {
// URL数据库连接串信息,ip未你的IP地址,“1521”为端口,“orcl”为sid
String URL = "jdbc:oracle:thin:@ip:1521:orcl";
String user = "scott"; //数据库用户名
String password = "password"; //登陆数据库密码
Connection conn = null;
Statement stmt;
// 初始化连接
public JdbcText){
try
{
//构造驱动实例
Class.forName"oracle.jdbc.driver.OracleDriver").newInstance);
// 与url指定的数据源建立连接
conn = DriverManager.getConnectionURL, user, password);
System.out.println"成功连接数据库!");
// 采用Statement进行查询
stmt = conn.createStatement); // 创建连接状态对象
} catch Exception e)
{
System.out.println"连接数据库失败!");
e.printStackTrace);
}
}
// 执行查询 获取结果存入容器中
public ResultSet executeQueryString sql) {
ResultSet rs = null;
try
{
rs = stmt.executeQuerysql); //执行SQL语句,将获取内容存入 rs
} catch SQLException e)
{
System.out.println"SQL语句书写错误!");
e.printStackTrace);
}
return rs;
}
public void close) {
try
{
conn.close);
stmt.close);
} catch Exception e)
{
e.printStackTrace);
}
}
public static void mainString[] args) {
ResultSet rs;
JdbcText jdbc = new JdbcText);
rs = jdbc.executeQuery"SELECT empno,ename from emp"); //从emp表中查询员工编号和姓名
try
{
while rs.next)) // 遍历结果集
{
System.out.printrs.getString"empno"));
System.out.println":" + rs.getString"ename"));
}
} catch Exception e)
{
e.printStackTrace);
}
jdbc.close);
}
}
首先保证你Oracle相关服务是正常打开的
可能出项的异常:
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
没有加载数据库驱动
解决:导入class12.jar包
若还是连接数据库失败,那把IP地址改为 localhost 或你的计算机名(至于原因,还未解决,如果你能解决,还请告知一声)
若报SQL异常,就好好检查一下你的 SQL语句吧
————————————————————————————————————————————————————————————————————————————
5、JVM性能调优,都做了什么?
———————————————————————————————————————————————————
一、CPU过高
1、 us过高
使用监控工具快读定位哪里有死循环,大计算,对于死循环通过阻塞式队列解决,对于大计算,建议分配单独的机器做后台计算,尽量不要影响用户交互,如果一定要的话(如框计算、云计算),只能通过大量分布式来实现
2、 sy过高
最有效的方法就是减少进程,不是进程越多效率越高,一般来说线程数和CPU的核心数相同,这样既不会造成线程切换,又不会浪费CPU资源
二、内存消耗过高
1、 及时释放不必要的对象
2、 使用对象缓存池缓冲
3、 采用合理的缓存失效算法(还记得我们之前提到的弱引用、幽灵引用么?)
三、磁盘IO过高
1、 异步读写文件
2、 批量读写文件
3、 使用缓存技术
4、 采用合理的文件读写规则
四、网络
1、增加宽带流量
五、资源消耗不多但程序运行缓慢
1、使用并发包,减少锁竞争
2、对于必须单线程执行的使用队列处理
3、大量分布式处理
六、未充分利用硬件资源
1、 修改程序代码,使用多线程处理
2、 修正外部资源瓶颈,做业务拆分
3、 使用缓存
在CPU负载不足的同时,偶尔会有用户反映请求的时间过长,我们意识到必须对程序及JVM进行调优。从以下几个方面进行:
- 线程池:解决用户响应时间长的问题
- 连接池
- JVM启动参数:调整各代的内存比例和垃圾回收算法,提高吞吐量
- 程序算法:改进程序逻辑算法提高性能
———————————————————————————————————————————————————
6、forward和sendRedirect的区别
———————————————————————————————————————————————————
SendRedirect | Forward |
---|---|
不同的request | 不同的对象,但是可以渠道上一个页面的内容 |
send后面的语句会继续执行,除非return | Forward后面的语句不会继续发送给客户端 |
速度慢 | 速度快 |
需要到客户端的往返,可以跳转到任何页面 | 服务器内部转换 |
地址栏有变化 | 地址栏没有变化 |
可以传参数,直接写在URL后面 | 可以传参数 |
/ 代表的是http://127.0.0.0/ |
/ 代表的是 http://127.0.0.1/test |
ITeye sendRedirect和forward原理及区别总结
ITeye forward与sendRedirect区别
CSDN forward和sendRedirect的区别
HttpServletResponse.sendRedirect与RequestDispatcher.forward方法都可以实现获取相应URL资源。
sendRedirect实现请求重定向,forward实现的是请求转发。
在web服务器内部的处理机制也是不一样的。
1.forward方法只能转发给同一个web站点的资源,而sendRedirect方法还可以定位到同一个web站点的其他应用,甚至可以通过传入绝对路径定位到别的web站点,这事forward的方法所不能比拟的优势。
可以看到这两种方法的用法,如果传给RequestDispatcher 的参数以"/"开头,则访问的是当前web应用的根目录
加入当前web的根目录是myweb。如果传给sendRedirect方法以"/"开头,访问的是整个web站点的根目录。
[java] view plaincopyprint?
- RequestDispatcher rd = request.getRequestDispatcher"/index.jsp");
- rd.forwardrequest, response);
- response.sendRedirect"/index.jsp");
RequestDispatcher rd = request.getRequestDispatcher"/index.jsp");rd.forwardrequest, response);response.sendRedirect"/index.jsp");
2.forward重定向后,浏览器url地址不变,sendRedirect转发后,浏览器url地址变为目的url地址。
3. 使用forward重定向的过程,是浏览器先向目的Servlet发送一次Request请求,然后再服务器端由Servlet再将请求发送到目的url,再由服务器端Servlet返回Response到浏览器端。浏览器和服务器一次请求响应。
使用sendRedirect转发的过程,浏览器先向目的Servlet发送一次请求,Servlet看到sendRedirect将目的url返回到浏览器,浏览器再去请求目的url,目的url再返回response到浏览器。浏览器和服务器两次请求响应。
4. forward方法的调用者与被调用者之间共享Request和Response
sendRedirect方法由于两次浏览器服务器请求,所以有两个Request和Response。
如果使用request.setAttribute传递一些属性就需要用forward,如果想要跳转到别的应用的资源,就需要用sendRedirect。
5.无论是forward方法还是sendRedirect方法调用前面都不能有PrintWriter输出到客户端。
forward方法报错: java.lang.IllegalStateException: Cannot forward after response has been committed
sendRedirect报错:java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirectResponseFacade.java:435)
———————————————————————————————————————————————————
6、<jsp:include page=''> 和 <%@include file=''%>的区别
———————————————————————————————————————————————————
1.<jsp:include page=""/>是运行时包含,面向的是静态和动态对象,其JSP引擎不对所包含的文件进行语法分析。
2.<%@ include file="" %>是编译时包含,面向的仅是静态的对象,其JSP引擎对所包含的文件进行语法分析。
所以在使用一个jsp页面包含另一个页面时要注意,如果另一个页面是静态不重新加载的页面或者是两个页面不包含相同的变量时使用<%@ include file="" %>,否则使用<jsp:include page=""/>。
———————————————————————————————————————————————————
7、你们系统的数据库切分,按什么切? 横向 纵向切分?
———————————————————————————————————————————————————
数据的切分分为两种模式,一种是按照不同的表或者schema)来切分到不同的数据库主机)上,这种切分可以称之为垂直(纵向)切分;另外一种是根据数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上,这种切分称之为数据的水平(横向)切分。
一个架构较好的应用系统,其总体功能肯定是由多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一个或多个表。而在架构设计中,各个功能模块相互之间的交互点越统一,越少,系统的耦合度就越低,系统各个模块的维护性及扩展性就越好。这样的系统,实现数据的垂直切分也就越容易。
数据的垂直切分基本上可以简单地理解为按照表或模块来切分数据,而水平切分则不同。一般来说,简单的水平切分主要是将某个访问及其平凡的表再按照某个字段的某种规则分散到多个表中,每个表包含一部分数据。就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他数据库中。为了容易地判定各行数据被切分到哪个数据库了,切分总是要按照某种特定的规则来进行的:如根据某个数据类型字段基于特定数据取模,某个时间类型字段的范围,或者某个字符类型字段的hash值。如果整个系统中大部分核心表都可以通过某个字段来进行关联,那这个字段自然是一个进行水平分区的上上之选了。
———————————————————————————————————————————————————
8、熟悉linux下的开发么?
____________________________________________________________________________________________
熟悉
____________________________________________________________________________________________
9、tcp头部都什么东西,http呢?
____________________________________________________________________________________________
HTTP 头部解释
1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。
2. Accept-Charset: 浏览器申明自己接收的字符集
Accept-Encoding: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法 (gzip,deflate)
Accept-Language::浏览器申明自己接收的语言语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。
3. Accept-Ranges:WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。
4. Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。
5. Authorization:当客户端接收到来自WEB服务器的 WWW-Authenticate 响应时,该头部来回应自己的身份验证信息给WEB服务器。
6. Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB服务器去取)
max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象)
max-stale:(可以接受过去的对象,但是过期时间必须小于
max-stale 值)
min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的
缓存对象)
响应:public可以用 Cached 内容回应任何用户)
private(只能用缓存内容回应先前请求该内容的那个用户)
no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端)
max-age:(本响应包含的对象的过期时间)
ALL: no-store(不允许缓存)
7. Connection:请求:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应
后,断开连接,不要等待本次连接的后续请求了)。
keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的
响应后,保持连接,等待本次连接的后续请求)。
响应:close(连接已经关闭)。
keepalive(连接保持着,在等待本次连接的后续请求)。
Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持
连接多长时间(秒)。
例如:Keep-Alive:300
8. Content-Encoding:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。
例如:Content-Encoding:gzip
Content-Language:WEB 服务器告诉浏览器自己响应的对象的语言。
Content-Length: WEB 服务器告诉浏览器自己响应的对象的长度。
例如:Content-Length: 26012
Content-Range: WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。
例如:Content-Range: bytes 21010-47021/47022
Content-Type: WEB 服务器告诉浏览器自己响应的对象的类型。
例如:Content-Type:application/xml
9. ETag:就是一个对象(比如URL)的标志值,就一个对象而言,比如一个 html 文件,
如果被修改了,其 Etag 也会别修改, 所以,ETag 的作用跟 Last-Modified 的
作用差不多,主要供 WEB 服务器 判断一个对象是否改变了。
比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时,
浏览器就会把先前获得的 ETag 值发送给 WEB 服务器,然后 WEB 服务器
会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件
有没有改变了。
10. Expired:WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在
跟WEB服务器验证了其有效性后,才能用来响应客户请求。
是 HTTP/1.0 的头部。
例如:Expires:Sat, 23 May 2009 10:02:12 GMT
11. Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。
例如:Host:rss.sina.com.cn
12. If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。
If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。
13. If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求
的动作(比如返回对象),否则返回代码304,告诉浏览器该对象
没有修改。
例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT
If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行
请求的动作(比如返回对象)。
14. If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分
给我,如果对象改变了,就把整个对象给我。 浏览器通过发送请求对象的
ETag 或者 自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否
改变了。
总是跟 Range 头部一起使用。
15. Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,
动态页面的最后产生时间等等。
例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT
16. Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,
到该头部指定的位置去取。
例如:Location:
http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif
17. Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control: no-cache。
例如:Pragma:no-cache
18. Proxy-Authenticate: 代理服务器响应浏览器,要求其提供代理身份验证信息。
Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。
19. Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。
例如:Range: bytes=1173546-
20. Referer:浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。
例如:Referer:http://www.sina.com/
21. Server: WEB 服务器表明自己是什么软件及版本等信息。
例如:Server:Apache/2.0.61 Unix)
22. User-Agent: 浏览器表明自己的身份(是哪种浏览器)。
例如:User-Agent:Mozilla/5.0 Windows; U; Windows NT 5.1; zh-CN;
rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14
23. Transfer-Encoding: WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)
作了怎样的编码,比如是否分块(chunked)。
例如:Transfer-Encoding: chunked
24. Vary: WEB服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应
所返回的对象响应后续的请求。
假如源WEB服务器在接到第一个请求消息时,其响应消息的头部为:
Content-Encoding: gzip; Vary: Content-Encoding 那么 Cache 服务器会分析后续
请求消息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值
一致,即是否使用相同的内容编码方法,这样就可以防止 Cache 服务器用自己
Cache 里面压缩后的实体响应给不具备解压能力的浏览器。
例如:Vary:Accept-Encoding
25. Via: 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用
什么协议(和版本)发送的请求。
当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面
添加 Via 头部,并填上自己的相关信息,当下一个代理服务器 收到第一个代理
服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via
头部,并把自己的相关信息加到后面, 以此类推,当 OCS 收到最后一个代理服
务器的请求时,检查 Via 头部,就知道该请求所经过的路由。
例如:Via:1.0 236-81.D07071953.sina.com.cn:80 squid/2.6.STABLE13
1)IPv4 头部
版本 IP报文首部的第一个字段是4位版本字段。对IPv4来说,这个字段的值是4。
首部长度(IHL) 第二个字段是4位首部长度,说明首部有多少32位字长。由于IPv4首部可能包含数目不定的选项,这个字段也用来确定数据的偏移量。这个字段的最小值是5(RFC 791),最大值是15。
服务类型(TOS) 在转发过程中用来提供特别的服务。
全长 这个16位字段定义了报文总长,包含首部和数据,单位为字节。这个字段的最小值是20(20字节首部+0字节数据),最大值是65,535。所有主机都必须支持最小576字节的报文,但大多数现代主机支持更大的报文。有时候子网会限制报文的大小,这时报文就必须被分片。
标识符 这个字段主要被用来唯一地标识一个报文的所有分片。一些实验性的工作建议将此字段用于其它目的,例如增加报文跟踪信息以协助探测伪造的源地址。[5]
标志 这个3位字段用于控制和识别分片,它们是:
位0:保留,必须为0;
位1:禁止分片(DF);
位2:更多分片(MF)。
如果DF标志被设置但路由要求必须分片报文,此报文会被丢弃。这个标志可被用于发往没有能力组装分片的主机。
当一个报文被分片,除了最后一片外的所有分片都设置MF标志。不被分片的报文不设置MF标志:它是它自己的最后一片。
分片偏移 这个13位字段指明了每个分片相对于原始报文开头的偏移量,以8字节作单位。
存活时间(TTL) 这个8位字段避免报文在互联网中永远存在(例如陷入路由环路)。存活时间以秒为单位,但小于一秒的时间均向上取整到一秒。在现实中,这实际上成了一个跳数计数器:报文经过的每个路由器都将此字段减一,当此字段等于0时,报文不再向下一跳传送并被丢弃。常规地,一份ICMP报文被发回报文发送端说明其发送的报文已被丢弃。这也是traceroute的核心原理。
协议 这个字段定义了该报文数据区使用的协议。IANA维护着一份协议列表(最初由RFC 790定义)。
首部检验和 这个16位检验和字段用于对首部查错。在每一跳,计算出的首部检验和必须与此字段进行比对,如果不一致,此报文被丢弃。
源地址 一个IPv4地址由四个字节共32位构成,此字段的值是将每个字节转为二进制并拼在一起所得到的32位值。
目的地址 与源地址格式相同,但指出报文的接收端。
选项 附加的首部字段可能跟在目的地址之后,但这并不被经常使用。
(2)IPv6头部
(3)UDP 头部
(4)TCP 头部
____________________________________________________________________________________________
10、加密解密的东西做过么?如md5什么的
____________________________________________________________________________________________
加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密有些资料将加密直接分为对称加密和非对称加密)。
双向加密大体意思就是明文加密后形成密文,可以通过算法还原成明文。而单向加密只是对信息进行了摘要计算,不能通过算法生成明文,单向加密从严格意思上说不能算是加密的一种,应该算是摘要算法吧。具体区分可以参考:
本人解释不清呢 …… )
http://security.group.iteye.com/group/wiki/1710-one-way-encryption-algorithm
一、双向加密
一)、对称加密
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
需要对加密和解密使用相同密钥的加密算法。由于其速度,对称性加密通常在消息发送方需要加密大量数据时使用。对称性加密也称为密钥加密。
所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。
算法是一组规则,规定如何进行加密和解密。因此对称式加密本身不是安全的。
常用的对称加密有:DES、IDEA、RC2、RC4、SKIPJACK、RC5、AES算法等
对称加密一般java类中中定义成员
Java代码
- //KeyGenerator 提供对称密钥生成器的功能,支持各种算法
- private KeyGenerator keygen;
- //SecretKey 负责保存对称密钥
- private SecretKey deskey;
- //Cipher负责完成加密或解密工作
- private Cipher c;
- //该字节数组负责保存加密的结果
- private byte[] cipherByte;
//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;
在构造函数中初始化
Java代码
- Security.addProvidernew com.sun.crypto.provider.SunJCE));
- //实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)
- keygen = KeyGenerator.getInstance"DES");//
- //生成密钥
- deskey = keygen.generateKey);
- //生成Cipher对象,指定其支持的DES算法
- c = Cipher.getInstance"DES");
Security.addProvidernew com.sun.crypto.provider.SunJCE));
//实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance"DES");//
//生成密钥
deskey = keygen.generateKey);
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance"DES");
1. DES算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。 明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
Java代码
- import java.security.InvalidKeyException;
- import java.security.NoSuchAlgorithmException;
- import java.security.Security;
- import javax.crypto.BadPaddingException;
- import javax.crypto.Cipher;
- import javax.crypto.IllegalBlockSizeException;
- import javax.crypto.KeyGenerator;
- import javax.crypto.NoSuchPaddingException;
- import javax.crypto.SecretKey;
- public class EncrypDES {
- //KeyGenerator 提供对称密钥生成器的功能,支持各种算法
- private KeyGenerator keygen;
- //SecretKey 负责保存对称密钥
- private SecretKey deskey;
- //Cipher负责完成加密或解密工作
- private Cipher c;
- //该字节数组负责保存加密的结果
- private byte[] cipherByte;
- public EncrypDES) throws NoSuchAlgorithmException, NoSuchPaddingException{
- Security.addProvidernew com.sun.crypto.provider.SunJCE));
- //实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)
- keygen = KeyGenerator.getInstance"DES");
- //生成密钥
- deskey = keygen.generateKey);
- //生成Cipher对象,指定其支持的DES算法
- c = Cipher.getInstance"DES");
- }
- /**
- * 对字符串加密
- *
- * @param str
- * @return
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- public byte[] EncrytorString str) throws InvalidKeyException,
- IllegalBlockSizeException, BadPaddingException {
- // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
- c.initCipher.ENCRYPT_MODE, deskey);
- byte[] src = str.getBytes);
- // 加密,结果保存进cipherByte
- cipherByte = c.doFinalsrc);
- return cipherByte;
- }
- /**
- * 对字符串解密
- *
- * @param buff
- * @return
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- public byte[] Decryptorbyte[] buff) throws InvalidKeyException,
- IllegalBlockSizeException, BadPaddingException {
- // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
- c.initCipher.DECRYPT_MODE, deskey);
- cipherByte = c.doFinalbuff);
- return cipherByte;
- }
- /**
- * @param args
- * @throws NoSuchPaddingException
- * @throws NoSuchAlgorithmException
- * @throws BadPaddingException
- * @throws IllegalBlockSizeException
- * @throws InvalidKeyException
- */
- public static void mainString[] args) throws Exception {
- EncrypDES de1 = new EncrypDES);
- String msg ="郭XX-搞笑相声全集";
- byte[] encontent = de1.Encrytormsg);
- byte[] decontent = de1.Decryptorencontent);
- System.out.println"明文是:" + msg);
- System.out.println"加密后:" + new Stringencontent));
- System.out.println"解密后:" + new Stringdecontent));
- }
- }
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;public class EncrypDES {//KeyGenerator 提供对称密钥生成器的功能,支持各种算法private KeyGenerator keygen;//SecretKey 负责保存对称密钥private SecretKey deskey;//Cipher负责完成加密或解密工作private Cipher c;//该字节数组负责保存加密的结果private byte[] cipherByte;public EncrypDES) throws NoSuchAlgorithmException, NoSuchPaddingException{Security.addProvidernew com.sun.crypto.provider.SunJCE));//实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)keygen = KeyGenerator.getInstance"DES");//生成密钥deskey = keygen.generateKey);//生成Cipher对象,指定其支持的DES算法c = Cipher.getInstance"DES");}/*** 对字符串加密* * @param str* @return* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/public byte[] EncrytorString str) throws InvalidKeyException,IllegalBlockSizeException, BadPaddingException {// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式c.initCipher.ENCRYPT_MODE, deskey);byte[] src = str.getBytes);// 加密,结果保存进cipherBytecipherByte = c.doFinalsrc);return cipherByte;}/*** 对字符串解密* * @param buff* @return* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/public byte[] Decryptorbyte[] buff) throws InvalidKeyException,IllegalBlockSizeException, BadPaddingException {// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式c.initCipher.DECRYPT_MODE, deskey);cipherByte = c.doFinalbuff);return cipherByte;}/*** @param args* @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */public static void mainString[] args) throws Exception {EncrypDES de1 = new EncrypDES);String msg ="郭XX-搞笑相声全集";byte[] encontent = de1.Encrytormsg);byte[] decontent = de1.Decryptorencontent);System.out.println"明文是:" + msg);System.out.println"加密后:" + new Stringencontent));System.out.println"解密后:" + new Stringdecontent));}}
2. 3DES又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对3DES
数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。
3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法,其具体实现如下:
设Ek)和Dk)代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密文,
这样,
3DES加密过程为:C=Ek3Dk2Ek1P)))
3DES解密过程为:P=Dk1EK2Dk3C)))
Java代码
- import java.security.InvalidKeyException;
- import java.security.NoSuchAlgorithmException;
- import java.security.Security;
- import javax.crypto.BadPaddingException;
- import javax.crypto.Cipher;
- import javax.crypto.IllegalBlockSizeException;
- import javax.crypto.KeyGenerator;
- import javax.crypto.NoSuchPaddingException;
- import javax.crypto.SecretKey;
- public class EncrypDES3 {
- // KeyGenerator 提供对称密钥生成器的功能,支持各种算法
- private KeyGenerator keygen;
- // SecretKey 负责保存对称密钥
- private SecretKey deskey;
- // Cipher负责完成加密或解密工作
- private Cipher c;
- // 该字节数组负责保存加密的结果
- private byte[] cipherByte;
- public EncrypDES3) throws NoSuchAlgorithmException, NoSuchPaddingException {
- Security.addProvidernew com.sun.crypto.provider.SunJCE));
- // 实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)
- keygen = KeyGenerator.getInstance"DESede");
- // 生成密钥
- deskey = keygen.generateKey);
- // 生成Cipher对象,指定其支持的DES算法
- c = Cipher.getInstance"DESede");
- }
- /**
- * 对字符串加密
- *
- * @param str
- * @return
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- public byte[] EncrytorString str) throws InvalidKeyException,
- IllegalBlockSizeException, BadPaddingException {
- // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
- c.initCipher.ENCRYPT_MODE, deskey);
- byte[] src = str.getBytes);
- // 加密,结果保存进cipherByte
- cipherByte = c.doFinalsrc);
- return cipherByte;
- }
- /**
- * 对字符串解密
- *
- * @param buff
- * @return
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- public byte[] Decryptorbyte[] buff) throws InvalidKeyException,
- IllegalBlockSizeException, BadPaddingException {
- // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
- c.initCipher.DECRYPT_MODE, deskey);
- cipherByte = c.doFinalbuff);
- return cipherByte;
- }
- /**
- * @param args
- * @throws NoSuchPaddingException
- * @throws NoSuchAlgorithmException
- * @throws BadPaddingException
- * @throws IllegalBlockSizeException
- * @throws InvalidKeyException
- */
- public static void mainString[] args) throws Exception {
- EncrypDES3 des = new EncrypDES3);
- String msg ="郭XX-搞笑相声全集";
- byte[] encontent = des.Encrytormsg);
- byte[] decontent = des.Decryptorencontent);
- System.out.println"明文是:" + msg);
- System.out.println"加密后:" + new Stringencontent));
- System.out.println"解密后:" + new Stringdecontent));
- }
- }
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;public class EncrypDES3 {// KeyGenerator 提供对称密钥生成器的功能,支持各种算法private KeyGenerator keygen;// SecretKey 负责保存对称密钥private SecretKey deskey;// Cipher负责完成加密或解密工作private Cipher c;// 该字节数组负责保存加密的结果private byte[] cipherByte;public EncrypDES3) throws NoSuchAlgorithmException, NoSuchPaddingException {Security.addProvidernew com.sun.crypto.provider.SunJCE));// 实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)keygen = KeyGenerator.getInstance"DESede");// 生成密钥deskey = keygen.generateKey);// 生成Cipher对象,指定其支持的DES算法c = Cipher.getInstance"DESede");}/*** 对字符串加密* * @param str* @return* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/public byte[] EncrytorString str) throws InvalidKeyException,IllegalBlockSizeException, BadPaddingException {// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式c.initCipher.ENCRYPT_MODE, deskey);byte[] src = str.getBytes);// 加密,结果保存进cipherBytecipherByte = c.doFinalsrc);return cipherByte;}/*** 对字符串解密* * @param buff* @return* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/public byte[] Decryptorbyte[] buff) throws InvalidKeyException,IllegalBlockSizeException, BadPaddingException {// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式c.initCipher.DECRYPT_MODE, deskey);cipherByte = c.doFinalbuff);return cipherByte;}/*** @param args* @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */public static void mainString[] args) throws Exception {EncrypDES3 des = new EncrypDES3);String msg ="郭XX-搞笑相声全集";byte[] encontent = des.Encrytormsg);byte[] decontent = des.Decryptorencontent);System.out.println"明文是:" + msg);System.out.println"加密后:" + new Stringencontent));System.out.println"解密后:" + new Stringdecontent));}}
3. AES密码学中的高级加密标准(Advanced Encryption Standard,AES),又称 高级加密标准
Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。 该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhinedoll"。)
Java代码
- import java.security.InvalidKeyException;
- import java.security.NoSuchAlgorithmException;
- import java.security.Security;
- import javax.crypto.BadPaddingException;
- import javax.crypto.Cipher;
- import javax.crypto.IllegalBlockSizeException;
- import javax.crypto.KeyGenerator;
- import javax.crypto.NoSuchPaddingException;
- import javax.crypto.SecretKey;
- public class EncrypAES {
- //KeyGenerator 提供对称密钥生成器的功能,支持各种算法
- private KeyGenerator keygen;
- //SecretKey 负责保存对称密钥
- private SecretKey deskey;
- //Cipher负责完成加密或解密工作
- private Cipher c;
- //该字节数组负责保存加密的结果
- private byte[] cipherByte;
- public EncrypAES) throws NoSuchAlgorithmException, NoSuchPaddingException{
- Security.addProvidernew com.sun.crypto.provider.SunJCE));
- //实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)
- keygen = KeyGenerator.getInstance"AES");
- //生成密钥
- deskey = keygen.generateKey);
- //生成Cipher对象,指定其支持的DES算法
- c = Cipher.getInstance"AES");
- }
- /**
- * 对字符串加密
- *
- * @param str
- * @return
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- public byte[] EncrytorString str) throws InvalidKeyException,
- IllegalBlockSizeException, BadPaddingException {
- // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
- c.initCipher.ENCRYPT_MODE, deskey);
- byte[] src = str.getBytes);
- // 加密,结果保存进cipherByte
- cipherByte = c.doFinalsrc);
- return cipherByte;
- }
- /**
- * 对字符串解密
- *
- * @param buff
- * @return
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- public byte[] Decryptorbyte[] buff) throws InvalidKeyException,
- IllegalBlockSizeException, BadPaddingException {
- // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
- c.initCipher.DECRYPT_MODE, deskey);
- cipherByte = c.doFinalbuff);
- return cipherByte;
- }
- /**
- * @param args
- * @throws NoSuchPaddingException
- * @throws NoSuchAlgorithmException
- * @throws BadPaddingException
- * @throws IllegalBlockSizeException
- * @throws InvalidKeyException
- */
- public static void mainString[] args) throws Exception {
- EncrypAES de1 = new EncrypAES);
- String msg ="郭XX-搞笑相声全集";
- byte[] encontent = de1.Encrytormsg);
- byte[] decontent = de1.Decryptorencontent);
- System.out.println"明文是:" + msg);
- System.out.println"加密后:" + new Stringencontent));
- System.out.println"解密后:" + new Stringdecontent));
- }
- }
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;public class EncrypAES {//KeyGenerator 提供对称密钥生成器的功能,支持各种算法private KeyGenerator keygen;//SecretKey 负责保存对称密钥private SecretKey deskey;//Cipher负责完成加密或解密工作private Cipher c;//该字节数组负责保存加密的结果private byte[] cipherByte;public EncrypAES) throws NoSuchAlgorithmException, NoSuchPaddingException{Security.addProvidernew com.sun.crypto.provider.SunJCE));//实例化支持DES算法的密钥生成器算法名称命名需按规定,否则抛出异常)keygen = KeyGenerator.getInstance"AES");//生成密钥deskey = keygen.generateKey);//生成Cipher对象,指定其支持的DES算法c = Cipher.getInstance"AES");}/*** 对字符串加密* * @param str* @return* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/public byte[] EncrytorString str) throws InvalidKeyException,IllegalBlockSizeException, BadPaddingException {// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式c.initCipher.ENCRYPT_MODE, deskey);byte[] src = str.getBytes);// 加密,结果保存进cipherBytecipherByte = c.doFinalsrc);return cipherByte;}/*** 对字符串解密* * @param buff* @return* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/public byte[] Decryptorbyte[] buff) throws InvalidKeyException,IllegalBlockSizeException, BadPaddingException {// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式c.initCipher.DECRYPT_MODE, deskey);cipherByte = c.doFinalbuff);return cipherByte;}/*** @param args* @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */public static void mainString[] args) throws Exception {EncrypAES de1 = new EncrypAES);String msg ="郭XX-搞笑相声全集";byte[] encontent = de1.Encrytormsg);byte[] decontent = de1.Decryptorencontent);System.out.println"明文是:" + msg);System.out.println"加密后:" + new Stringencontent));System.out.println"解密后:" + new Stringdecontent));}}
二)、非对称加密
1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥
(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
1. RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
Java代码
- import java.security.InvalidKeyException;
- import java.security.KeyPair;
- import java.security.KeyPairGenerator;
- import java.security.NoSuchAlgorithmException;
- import java.security.interfaces.RSAPrivateKey;
- import java.security.interfaces.RSAPublicKey;
- import javax.crypto.BadPaddingException;
- import javax.crypto.Cipher;
- import javax.crypto.IllegalBlockSizeException;
- import javax.crypto.NoSuchPaddingException;
- public class EncrypRSA {
- /**
- * 加密
- * @param publicKey
- * @param srcBytes
- * @return
- * @throws NoSuchAlgorithmException
- * @throws NoSuchPaddingException
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- protected byte[] encryptRSAPublicKey publicKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
- ifpublicKey!=null){
- //Cipher负责完成加密或解密工作,基于RSA
- Cipher cipher = Cipher.getInstance"RSA");
- //根据公钥,对Cipher对象进行初始化
- cipher.initCipher.ENCRYPT_MODE, publicKey);
- byte[] resultBytes = cipher.doFinalsrcBytes);
- return resultBytes;
- }
- return null;
- }
- /**
- * 解密
- * @param privateKey
- * @param srcBytes
- * @return
- * @throws NoSuchAlgorithmException
- * @throws NoSuchPaddingException
- * @throws InvalidKeyException
- * @throws IllegalBlockSizeException
- * @throws BadPaddingException
- */
- protected byte[] decryptRSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
- ifprivateKey!=null){
- //Cipher负责完成加密或解密工作,基于RSA
- Cipher cipher = Cipher.getInstance"RSA");
- //根据公钥,对Cipher对象进行初始化
- cipher.initCipher.DECRYPT_MODE, privateKey);
- byte[] resultBytes = cipher.doFinalsrcBytes);
- return resultBytes;
- }
- return null;
- }
- /**
- * @param args
- * @throws NoSuchAlgorithmException
- * @throws BadPaddingException
- * @throws IllegalBlockSizeException
- * @throws NoSuchPaddingException
- * @throws InvalidKeyException
- */
- public static void mainString[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
- EncrypRSA rsa = new EncrypRSA);
- String msg = "郭XX-精品相声";
- //KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
- KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance"RSA");
- //初始化密钥对生成器,密钥大小为1024位
- keyPairGen.initialize1024);
- //生成一个密钥对,保存在keyPair中
- KeyPair keyPair = keyPairGen.generateKeyPair);
- //得到私钥
- RSAPrivateKey privateKey = RSAPrivateKey)keyPair.getPrivate);
- //得到公钥
- RSAPublicKey publicKey = RSAPublicKey)keyPair.getPublic);
- //用公钥加密
- byte[] srcBytes = msg.getBytes);
- byte[] resultBytes = rsa.encryptpublicKey, srcBytes);
- //用私钥解密
- byte[] decBytes = rsa.decryptprivateKey, resultBytes);
- System.out.println"明文是:" + msg);
- System.out.println"加密后是:" + new StringresultBytes));
- System.out.println"解密后是:" + new StringdecBytes));
- }
- }
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;public class EncrypRSA {/*** 加密* @param publicKey* @param srcBytes* @return* @throws NoSuchAlgorithmException* @throws NoSuchPaddingException* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/protected byte[] encryptRSAPublicKey publicKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ifpublicKey!=null){//Cipher负责完成加密或解密工作,基于RSACipher cipher = Cipher.getInstance"RSA");//根据公钥,对Cipher对象进行初始化cipher.initCipher.ENCRYPT_MODE, publicKey);byte[] resultBytes = cipher.doFinalsrcBytes);return resultBytes;}return null;}/*** 解密 * @param privateKey* @param srcBytes* @return* @throws NoSuchAlgorithmException* @throws NoSuchPaddingException* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/protected byte[] decryptRSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ifprivateKey!=null){//Cipher负责完成加密或解密工作,基于RSACipher cipher = Cipher.getInstance"RSA");//根据公钥,对Cipher对象进行初始化cipher.initCipher.DECRYPT_MODE, privateKey);byte[] resultBytes = cipher.doFinalsrcBytes);return resultBytes;}return null;}/*** @param args* @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws NoSuchPaddingException * @throws InvalidKeyException */public static void mainString[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {EncrypRSA rsa = new EncrypRSA);String msg = "郭XX-精品相声";//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance"RSA");//初始化密钥对生成器,密钥大小为1024位keyPairGen.initialize1024);//生成一个密钥对,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair);//得到私钥RSAPrivateKey privateKey = RSAPrivateKey)keyPair.getPrivate); //得到公钥RSAPublicKey publicKey = RSAPublicKey)keyPair.getPublic);//用公钥加密byte[] srcBytes = msg.getBytes);byte[] resultBytes = rsa.encryptpublicKey, srcBytes);//用私钥解密byte[] decBytes = rsa.decryptprivateKey, resultBytes);System.out.println"明文是:" + msg);System.out.println"加密后是:" + new StringresultBytes));System.out.println"解密后是:" + new StringdecBytes));}}
2. DSA
Digital Signature Algorithm DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSSDigitalSignature Standard)。感觉有点复杂,没有附代码)
详见http://63938525.iteye.com/blog/1051565
三)、题外话 MySQL加密解密函数
MySQL有两个函数来支持这种类型的加密,分别叫做ENCODE)和DECODE)。
下面是一个简单的实例:
Mysql代码
- mysql> INSERT INTO users username,password) VALUES 'joe',ENCODE'guessme','abr'));
- Query OK, 1 row affected (0.14 sec)
mysql> INSERT INTO users username,password) VALUES 'joe',ENCODE'guessme','abr'));Query OK, 1 row affected (0.14 sec)
其中,Joe的密码是guessme,它通过密钥abracadabra被加密。要注意的是,加密完的结果是一个二进制字符串,如下所示:
提示:虽然ENCODE)和DECODE)这两个函数能够满足大多数的要求,但是有的时候您希望使用强度更高的加密手段。在这种情况下,您可以使用AES_ENCRYPT)和AES_DECRYPT)函数,它们的工作方式是相同的,但是加密强度更高。
单向加密与双向加密不同,一旦数据被加密就没有办法颠倒这一过程。因此密码的验证包括对用户输入内容的重新加密,并将它与保存的密文进行比对,看是否匹配。一种简单的单向加密方式是MD5校验码。MySQL的MD5()函数会为您的数据创建一个“指纹”并将它保存起来,供验证测试使用。下面就是如何使用它的一个简单例子:
Mysql代码
- mysql> INSERT INTO users username,password) VALUES 'joe',MD5'guessme'));
- Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO users username,password) VALUES 'joe',MD5'guessme'));Query OK, 1 row affected (0.00 sec)
或者,您考虑一下使用ENCRYPT()函数,它使用系统底层的crypt()系统调用来完成加密。这个函数有两个参数:一个是要被加密的字符串,另一个是双(或者多)字符的“salt”。它然后会用salt加密字符串;这个salt然后可以被用来再次加密用户输入的内容,并将它与先前加密的字符串进行比对。下面一个例子说明了如何使用它:
Mysql代码
- mysql> INSERT INTO users username,password) VALUES'joe', ENCRYPT'guessme','ab'));
- Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO users username,password) VALUES'joe', ENCRYPT'guessme','ab'));Query OK, 1 row affected (0.00 sec)
提示:ENCRYPT)只能用在UNIX、LINIX系统上,因为它需要用到底层的crypt)库。
二、单向加密信息摘要)
Java一般需要获取对象MessageDigest来实现单项加密信息摘要)。
1. MD5 即Message-Digest Algorithm 5(信息-摘要算法 5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。
除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等
Java代码
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- public class EncrypMD5 {
- public byte[] eccryptString info) throws NoSuchAlgorithmException{
- //根据MD5算法生成MessageDigest对象
- MessageDigest md5 = MessageDigest.getInstance"MD5");
- byte[] srcBytes = info.getBytes);
- //使用srcBytes更新摘要
- md5.updatesrcBytes);
- //完成哈希计算,得到result
- byte[] resultBytes = md5.digest);
- return resultBytes;
- }
- public static void mainString args[]) throws NoSuchAlgorithmException{
- String msg = "郭XX-精品相声技术";
- EncrypMD5 md5 = new EncrypMD5);
- byte[] resultBytes = md5.eccryptmsg);
- System.out.println"密文是:" + new StringresultBytes));
- System.out.println"明文是:" + msg);
- }
- }
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class EncrypMD5 {public byte[] eccryptString info) throws NoSuchAlgorithmException{//根据MD5算法生成MessageDigest对象MessageDigest md5 = MessageDigest.getInstance"MD5");byte[] srcBytes = info.getBytes);//使用srcBytes更新摘要md5.updatesrcBytes);//完成哈希计算,得到resultbyte[] resultBytes = md5.digest);return resultBytes;}public static void mainString args[]) throws NoSuchAlgorithmException{String msg = "郭XX-精品相声技术";EncrypMD5 md5 = new EncrypMD5);byte[] resultBytes = md5.eccryptmsg);System.out.println"密文是:" + new StringresultBytes));System.out.println"明文是:" + msg);}}
2. SHA 是一种数据加密算法,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说时对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。
Java代码
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- public class EncrypSHA {
- public byte[] eccryptString info) throws NoSuchAlgorithmException{
- MessageDigest md5 = MessageDigest.getInstance"SHA");
- byte[] srcBytes = info.getBytes);
- //使用srcBytes更新摘要
- md5.updatesrcBytes);
- //完成哈希计算,得到result
- byte[] resultBytes = md5.digest);
- return resultBytes;
- }
- /**
- * @param args
- * @throws NoSuchAlgorithmException
- */
- public static void mainString[] args) throws NoSuchAlgorithmException {
- String msg = "郭XX-精品相声技术";
- EncrypSHA sha = new EncrypSHA);
- byte[] resultBytes = sha.eccryptmsg);
- System.out.println"明文是:" + msg);
- System.out.println"密文是:" + new StringresultBytes));
- }
- }
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class EncrypSHA {public byte[] eccryptString info) throws NoSuchAlgorithmException{MessageDigest md5 = MessageDigest.getInstance"SHA");byte[] srcBytes = info.getBytes);//使用srcBytes更新摘要md5.updatesrcBytes);//完成哈希计算,得到resultbyte[] resultBytes = md5.digest);return resultBytes;}/*** @param args* @throws NoSuchAlgorithmException */public static void mainString[] args) throws NoSuchAlgorithmException {String msg = "郭XX-精品相声技术";EncrypSHA sha = new EncrypSHA);byte[] resultBytes = sha.eccryptmsg);System.out.println"明文是:" + msg);System.out.println"密文是:" + new StringresultBytes));}}
附件中是以上几种的源代码,附带额外的两种使用方式。
增加一种关于文件的哈希算法源代码:
Java代码
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.security.MessageDigest;
- public class FileHashUtil {
- public static final char[] hexChar = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- public static final String[] hashTypes = new String[] { "MD2", "MD5", "SHA1", "SHA-256", "SHA-384", "SHA-512" };
- public void MD5FileString fileName) throws Exception{
- //String fileName = args[0];
- System.out.println"需要获取hash的文件为: " + fileName);
- java.util.List<MessageDigest> mds = new java.util.ArrayList<MessageDigest>);
- for String hashType : hashTypes) {
- MessageDigest md = MessageDigest.getInstancehashType);
- mds.addmd);
- }
- InputStream fis = null;
- try {
- fis = new FileInputStreamfileName);
- byte[] buffer = new byte[1024];
- int numRead = 0;
- while numRead = fis.readbuffer)) > 0) {
- for MessageDigest md : mds) {
- md.updatebuffer, 0, numRead);
- }
- }
- } catch Exception ex) {
- ex.printStackTrace);
- } finally {
- if fis != null) {
- fis.close);
- }
- }
- for MessageDigest md : mds) {
- System.out.printlnmd.getAlgorithm) + " == " + toHexStringmd.digest)));
- }
- }
- public static void mainString[] args) throws Exception {
- String[] fileName = new String[] {"D:/hapfish/ShellFolder.java","D:/hapfish/ShellFolder – 副本.java",
- "E:/ShellFolder – 副本.java","E:/ShellFolder.txt","D:/hapfish/ShellFolder.jpg",
- "E:/ShellFolder增加字符.txt","D:/hapfish/birosoft.jar"};
- FileHashUtil files = new FileHashUtil);
- forint i=0;i<fileName.length;i++){
- files.MD5FilefileName[i]);
- }
- }
- public static String toHexStringbyte[] b) {
- StringBuilder sb = new StringBuilderb.length * 2);
- for int i = 0; i < b.length; i++) {
- sb.appendhexChar[b[i] & 0xf0) >>> 4]);
- sb.appendhexChar[b[i] & 0x0f]);
- }
- return sb.toString);
- }
- }
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;public class FileHashUtil {public static final char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };public static final String[] hashTypes = new String[] { "MD2", "MD5", "SHA1", "SHA-256", "SHA-384", "SHA-512" };public void MD5FileString fileName) throws Exception{//String fileName = args[0];System.out.println"需要获取hash的文件为: " + fileName);java.util.List<MessageDigest> mds = new java.util.ArrayList<MessageDigest>);for String hashType : hashTypes) {MessageDigest md = MessageDigest.getInstancehashType);mds.addmd);}InputStream fis = null;try {fis = new FileInputStreamfileName);byte[] buffer = new byte[1024];int numRead = 0;while numRead = fis.readbuffer)) > 0) {for MessageDigest md : mds) {md.updatebuffer, 0, numRead);}}} catch Exception ex) {ex.printStackTrace);} finally {if fis != null) {fis.close);}}for MessageDigest md : mds) {System.out.printlnmd.getAlgorithm) + " == " + toHexStringmd.digest)));}}public static void mainString[] args) throws Exception {String[] fileName = new String[] {"D:/hapfish/ShellFolder.java","D:/hapfish/ShellFolder - 副本.java","E:/ShellFolder - 副本.java","E:/ShellFolder.txt","D:/hapfish/ShellFolder.jpg","E:/ShellFolder增加字符.txt","D:/hapfish/birosoft.jar"};FileHashUtil files = new FileHashUtil);forint i=0;i<fileName.length;i++){files.MD5FilefileName[i]);} }public static String toHexStringbyte[] b) {StringBuilder sb = new StringBuilderb.length * 2);for int i = 0; i < b.length; i++) {sb.appendhexChar[b[i] & 0xf0) >>> 4]);sb.appendhexChar[b[i] & 0x0f]);}return sb.toString);}}
运行说明
说明代码
- "D:/hapfish/ShellFolder.java",
- "D:/hapfish/ShellFolder – 副本.java",
- "E:/ShellFolder – 副本.java",
- "E:/ShellFolder.txt",
- "D:/hapfish/ShellFolder.jpg",
- 以上五个文件是同一文件经过复制、改扩展名的,最后计算哈希结果是一致的。
- "E:/ShellFolder增加字符.txt" 增加了几个字符串,就不一样了
- "D:/hapfish/birosoft.jar" 完全不相关的另外一个文件
"D:/hapfish/ShellFolder.java",
"D:/hapfish/ShellFolder - 副本.java",
"E:/ShellFolder - 副本.java",
"E:/ShellFolder.txt",
"D:/hapfish/ShellFolder.jpg",
以上五个文件是同一文件经过复制、改扩展名的,最后计算哈希结果是一致的。"E:/ShellFolder增加字符.txt" 增加了几个字符串,就不一样了"D:/hapfish/birosoft.jar" 完全不相关的另外一个文件
运行结果:
Java代码
- 需要获取hash的文件为: D:/hapfish/ShellFolder.java
- MD2 == 3a755a99c5e407005cd45ebd856b4649
- MD5 == 5d08d440fa911d1e418c69a90b83cd86
- SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
- SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
- SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
- SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
- 需要获取hash的文件为: D:/hapfish/ShellFolder – 副本.java
- MD2 == 3a755a99c5e407005cd45ebd856b4649
- MD5 == 5d08d440fa911d1e418c69a90b83cd86
- SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
- SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
- SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
- SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
- 需要获取hash的文件为: E:/ShellFolder – 副本.java
- MD2 == 3a755a99c5e407005cd45ebd856b4649
- MD5 == 5d08d440fa911d1e418c69a90b83cd86
- SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
- SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
- SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
- SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
- 需要获取hash的文件为: E:/ShellFolder.txt
- MD2 == 3a755a99c5e407005cd45ebd856b4649
- MD5 == 5d08d440fa911d1e418c69a90b83cd86
- SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
- SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
- SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
- SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
- 需要获取hash的文件为: D:/hapfish/ShellFolder.jpg
- MD2 == 3a755a99c5e407005cd45ebd856b4649
- MD5 == 5d08d440fa911d1e418c69a90b83cd86
- SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
- SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
- SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
- SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
- 需要获取hash的文件为: E:/ShellFolder增加字符.txt
- MD2 == f2717c24c6c0e110457bd17221c9ca6c
- MD5 == c49e353a7c4c26bd7ccb5e90917c230f
- SHA1 == 477c8a9e465bfaa4be42d35c032a17f7e6b42b97
- SHA-256 == 9fa18adaf242ebcdc6563922d84c2a163c82e1a24db2eb2b73978ed1f354a8a3
- SHA-384 == 4eee8f8e6d64d21c15dc01fa049f4d12a3b8e1d94d87763fe0bea75ab5ea8432fa8251289ece45ee39fe3d36b3c3020c
- SHA-512 == e852ec0ff77250be497389d2f5a1818c18bb66106b9905c4ee26fe0d256eb3b77e0ce9a28a84e4b67e4332ba37ec3aa7518148e3a682318c0fc34c391f45c201
- 需要获取hash的文件为: D:/hapfish/birosoft.jar
- MD2 == 38c5e1404718916dec59c33cafc909b3
- MD5 == dc3e2cc4fb3949cf3660e0f5f8c3fba3
- SHA1 == cde3dc25498afc5a563af0bb0eb54dc45f71bb28
- SHA-256 == adf6a961c70c6ea677dff066fc5d896fb0beb4dd442ca0eb619ae1d1b04291e5
- SHA-384 == fe7c6b754893c53ebd82bb53703fb5cc32115c9a38f98072f73def90729b271ee3c5c78e258bd9ff5ee5476193c2178b
- SHA-512 == a15376f327256a6e049dfbdc5c2ad3a98bffccc6fa92ee01ff53db6b04471ca0f45ca28f76ff4a6911b57825afa046671299141f2499d71f1dac618c92385491
需要获取hash的文件为: D:/hapfish/ShellFolder.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: D:/hapfish/ShellFolder - 副本.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder - 副本.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder.txt
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: D:/hapfish/ShellFolder.jpg
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder增加字符.txt
MD2 == f2717c24c6c0e110457bd17221c9ca6c
MD5 == c49e353a7c4c26bd7ccb5e90917c230f
SHA1 == 477c8a9e465bfaa4be42d35c032a17f7e6b42b97
SHA-256 == 9fa18adaf242ebcdc6563922d84c2a163c82e1a24db2eb2b73978ed1f354a8a3
SHA-384 == 4eee8f8e6d64d21c15dc01fa049f4d12a3b8e1d94d87763fe0bea75ab5ea8432fa8251289ece45ee39fe3d36b3c3020c
SHA-512 == e852ec0ff77250be497389d2f5a1818c18bb66106b9905c4ee26fe0d256eb3b77e0ce9a28a84e4b67e4332ba37ec3aa7518148e3a682318c0fc34c391f45c201
需要获取hash的文件为: D:/hapfish/birosoft.jar
MD2 == 38c5e1404718916dec59c33cafc909b3
MD5 == dc3e2cc4fb3949cf3660e0f5f8c3fba3
SHA1 == cde3dc25498afc5a563af0bb0eb54dc45f71bb28
SHA-256 == adf6a961c70c6ea677dff066fc5d896fb0beb4dd442ca0eb619ae1d1b04291e5
SHA-384 == fe7c6b754893c53ebd82bb53703fb5cc32115c9a38f98072f73def90729b271ee3c5c78e258bd9ff5ee5476193c2178b
SHA-512 == a15376f327256a6e049dfbdc5c2ad3a98bffccc6fa92ee01ff53db6b04471ca0f45ca28f76ff4a6911b57825afa046671299141f2499d71f1dac618c92385491
最后,把运行结果贴出来有点占空间,主要为了说明表述自己的猜想。一般来说同一哈希算法对同一文件镜像、扩展名被修改)所产生的结果应该是一致的。
因此有个猜想,在baidu文库、腾讯的群共享上传时,先会判断是否有相同文件,从某种可能上来说也采用了对文件的哈希算法,毕竟从本地运算一个哈希算法后获得的数值要比把整个文件传过去比较实惠得多。而且字符串的比较也是很方便的。
对于某一种哈希算法,存在一种可能:就是两个不同的文件,计算出来的哈希值可能是一样的。当然为了保险,可以用两种甚至更多的哈希算法,只有在每种算法获得的哈希值都相同时,才能判断是同一个文件。
如果我们也对用户上传的文件进行哈希计算的话,就可以节省资源,同样的文件按理说可以减少上传次数……
- my.rar 8.1 KB)
- 下载次数: 630
____________________________________________________________________________________________
tcp三次握手的过程,accept发生在三次握手哪个阶段?
accept发生在三次握手之后。
第一次握手:客户端发送syn包syn=j)到服务器。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ASK包(ask=k)。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACKack=k+1)。
三次握手完成后,客户端和服务器就建立了tcp连接。这时可以调用accept函数获得此连接。
___________________________________________________________________________________________
用UDP协议通讯时怎样得知目标机是否获得了数据包
用UDP协议通讯时怎样得知目标机是否获得了数据包?
可以在每个数据包中插入一个唯一的ID,比如timestamp或者递增的int。
发送方在发送数据时将此ID和发送时间记录在本地。
接收方在收到数据后将ID再发给发送方作为回应。
发送方如果收到回应,则知道接收方已经收到相应的数据包;如果在指定时间内没有收到回应,则数据包可能丢失,需要重复上面的过程重新发送一次,直到确定对方收到。
关于UDP协议的简单介绍,可以参考
——————————————————————————————————————————————————————————————————————
统计论坛在线人数分布
求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。
一天总共有 3600*24 = 86400秒。
定义一个长度为86400的整数数组int delta[86400],每个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。
然后依次读入每个用户的登录时间和退出时间,将与登录时间对应的整数值加1,将与退出时间对应的整数值减1。
这样处理一遍后数组中存储了每秒中的人数变化情况。
定义另外一个长度为86400的整数数组int online_num[86400],每个整数对应这一秒的论坛在线人数。
假设一天开始时论坛在线人数为0,则第1秒的人数online_num[0] = delta[0]。第n+1秒的人数online_num[n] = online_num[n-1] + delta[n]。
这样我们就获得了一天中任意时间的在线人数。
—————————————————————————————————————————————————————————————————————————————两个整数集合A和B,求其交集
两个整数集合A和B,求其交集。
1. 读取整数集合A中的整数,将读到的整数插入到map中,并将对应的值设为1。
2. 读取整数集合B中的整数,如果该整数在map中并且值为1,则将此数加入到交集当中,并将在map中的对应值改为2。
通过更改map中的值,避免了将同样的值输出两次。