it-e-45 How to Learn a New Language

How do you learn a new language? The fastest way is when you are forced to do so. But if
you're lucky enough to be learning by choice, you are probably doing it in your spare time and
you won't do that unless you are enjoying yourself  so choose an interesting project.
Choosing what you are going to write in your new language is more important than
choosing the language. Choose the language to suit the project or, better, choose both together.
For example, if you want to write something that will look good then don't choose a language
with no support for graphics.
Learn a little about the language before you start and try and find a solution that will play to
the language's new features. If you are using OOP for the first time, for example, try and think
how your project can be split into objects. If you are looking at functional programming, maybe a
numerical project would be a good start (I chose cryptography) (this suggestion does not imply
that functional languages are only useful for numerical code, just that most textbooks seem to
feature numerical examples in my limited experience making it easier to start in that
At the same time, be honest with yourself. Don't be too ambitious don't pick too difficult a
project and (maybe) don't pick too exotic a language. The second point is debatable. With any
language you will learn something new: it doesn't have to be a huge intellectual leap into the
unknown. You are going to be more productive in a language that has some familiar ideas, and
you can lean on that part of the language to get going. On the other hand, if you enjoy new ideas,
maybe you will be happier with something completely different.
Support is also important. If you intend to post questions to Usenet, is there an appropriate
newsgroup? Personally, I like booksÇthe best impetus for me is finding a good book on
computing that uses a particular language in the examples.
A note about asking for information on newsgroups: people seem to vary widely in how
precisely they talk about languages. At one end of the spectrum there are people who tend to rely
on a "subconscious" (or at least "sub-language") intuition and happily misuse terminology to "get
the idea across". At the other end are people who are very precise. Both, no doubt, will give
conflicting advice on how to learn and, sometimes, apparently conflicting answers to questions.
You have to learn to recognise different styles and read them in the context of the poster.
Finally, don't be afraid to change direction. I've stuck with a few languages much more than
with others. Sometimes I have given up in frustration. But even when you only play around a
little, you learn something. My argument is not that you must stay with a language a long time
to learn anything, but that the learning continues. Stay for a while and you'll learn something.
Stay longer and you'll learn more. there's no magic moment when you know everything (which
is what makes programming such a rewarding profession).

1, exotic  [,iɡ'zɔtik]
adj. 异国的;外来的;异国情调的

2, misuse  [,mis'ju:z, ,mis'ju:s]
vt. 滥用;误用;虐待
n. 滥用;误用;虐待
3, terminology  [,tə:mi'nɔlədʒi]
n. 术语,术语学;用辞
4, subconscious  [,sʌb'kɔnʃəs]
adj. 潜意识的;下意识的
n. 潜在意识;下意识心理活动
5, frustration  [frʌs'treiʃən]
n. 打破,挫折,顿挫
[计算机] 失败

Continue reading it-e-45 How to Learn a New Language

it-e-44 A Brief Word About Scripting

You've perhaps heard about something called scripting, or maybe you've heard of languages
like JavaScript, VBScript, Tcl and others (those languages are called scripting languages). You
may thus be wondering if scripting is the same as programming, and/or what the differences are,
and so on. People get quite passionate about this question, so I'm just going to cover it briefly and
technically. Here are some facts:
Scripting is essentially a type of programming.
Scripting languages have a few minor technical differences which aren't important to
discuss at this point.
Scripting languages tend to be interpreted rather than compiled, which means that you
don't need to compile them. they're compiled "on the fly" (i.e. when necessary, right
before they're run). This can make it faster to program in them (since you always have
the source code, and don't need to take the deliberate extra step of compiling).
The fact that scripting languages are interpreted generally makes them slower than.programming
languages for intensive operations (like complex calculations).
Scripting languages are often easier to learn than programming languages, but usually
aren't as powerful or flexible.
For programming things like applications for personal computers, you'll need to use a
programming language rather than a scripting language.
Scripting languages can be excellent for beginners: they tend to be easier to learn, and they
insulate you from some of the technical aspects of programming (compiling, for one). However,
if you're serious about programming, you won't be able to stay with a scripting language forever
you will move on to a programming language at some point. I'd say that it's good to know a
scripting language or two, and even to start with a scripting language rather than a programming
language. However, there's a point of view which says that, by protecting and "hand-holding" too
much, scripting languages don't properly prepare you for "serious" programming, and set you up
for a bit of a learning curve when you move on to a programming language.


1, deliberate  [di'libəreit]
a. 故意的,深思熟虑的
v. 仔细考虑
vt. 研讨

Continue reading it-e-44 A Brief Word About Scripting

it-e-43 Introduction of Programming Languages

A programming language is a defined set of instructions that are used to make a computer
perform a specific task. Written using a defined vocabulary the programming language is either
complied or interpreted by the computer into the machine
language that is understood by the processor.
There are several types of programming languages, the
most common are:
High-level Languages these are written using terms
and vocabulary that can be understood and written in a

similar manner to human language. [1] They are called high-level languages because they remove
many of the complexities involved in the raw machine language that computers understand. The
main advantage of high-level languages over low-level languages is that they are easier to read,
write, and maintain. All high-level languages must be compiled at some stage into machine
language. The first high-level programming languages were designed in the 1950s. Now there are
dozens of different languages, including BASIC, COBOL, C, C++, FORTRAN and Pascal.
Scripting Languages like high-level languages, scripting languages are written in manner
similar to human language. Generally, scripting languages are easier to write than high-level
languages and are interpreted rather compiled into machine language. Scripting languages, which
can be embedded within HTML, commonly are used to add functionality to a Web page, such as
different menu styles or graphic displays, or to serve dynamic advertisements. These types of
languages are client-side scripting languages, affecting the data that the end user sees in a
browser window. Other scripting languages are server-side scripting languages that manipulate
the data, usually in a database, on the server. Scripting languages came about largely because of
the development of the Internet as a communications tool. Some examples of scripting languages
include VBScript, JavaScript, ASP and Perl.
Assembly Language assembly language is as close as possible to writing directly in
machine language. Due to the low level nature of assembly language, it is tied directly to the type
of processor and a program written for one type of CPU generally will not run on another.
Machine language The lowest-level programming language. Machine languages are the only
languages understood by computers. While easily understood by computers, machine languages are
almost impossible for humans to use because they consist entirely of numbers. Programmers,
therefore, use either a high-level programming language or an assembly language. An assembly
language contains the same instructions as a machine language, but the instructions and variables
have names instead of being just numbers.
Programs written in high-level languages are translated into assembly language or machine
language by a compiler. Assembly language programs are translated into machine language by a
program called an assembler.
Every CPU has its own unique machine language. Programs must be rewritten or recompiled,
therefore, to run on different types of computers.
For now, let's talk about some high level languages very briefly, which are used by professional
programmers in the current mainstream software industry.
· C
This is probably the most widely-used, and definitely the oldest, of the three languages I
mentioned. It's been in use since the 70s, and is a very compact (i.e. not much "vocabulary" to
learn), powerful and well-understood language.
· C++
This language is a superset of C (that just means that it's C with more stuff added; it's more
than C, and includes pretty much all of C). Its main benefit over C is that it's object oriented.

The key point is that object oriented languages are more modern, and using object oriented
languages is the way things are done now in the programming world. So C++ is most definitely
the second-most used language after C, and may soon become the most used language.
· Java
Java has a benefit which other programming languages lack: it's cross-platform. It means
that it runs on more than one platform without needing to be recompiled. A platform is just a
particular type of computer system, like Windows or Mac OS or Linux. Normally, if you wanted
to use the same program on a different platform from the one it was written on, you'd have to
recompile it you'd have to compile a different version for each different platform. Sometimes,
you'd also need to change some of your code to suit the new platform. This probably isn't
surprising, since the different platforms work differently, and look different.
Java has another advantage that it runs inside web browsers, letting programmers create
little applications which can run on web sites. However, Java also has a disadvantage, which is
almost as serious: it's slow. Java achieves its cross-platform trick by putting what is essentially a
big program on your computer which pretends to be a little computer all of its own. The Java
runs inside this "virtual machine", which runs on whatever platform you're using (like Windows
or Mac OS). Because of this extra layer between the program and the computer's processor chip,
Java is slower than a program written and compiled natively for the same platform. Anyway, as
the Internet develops, Java will be used more widely.



Continue reading it-e-43 Introduction of Programming Languages

自己写html editor

简单的html editor 就是利用iframe的 document属性 designMode = 'on' 来让iframe可编辑。


		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<script type="text/javascript">
			function init()   
		        var doc = document.getElementById("EditForm").contentWindow.document;   
		            doc.designMode = 'on';
		            doc.write('<html><head><title></title><style type="text/css">p {margin: 0;padding: 0;}</style></head><body>fffffffffffffffffffff</body></html>');
	<body onLoad="init()">
		<iframe id="EditForm" frameborder="0"
			style="width: 700px; height: 400px; padding: 0; margin: 0; border: 1px solid #AAAAAA">

在IE和opera下,回车形成的行之间是用<p>(FF 下是<br>,chrome,safari是<div>)来包含的,造成行间距太大,因此要使用样式来修正。





其他使用selectionRange.deleteFromDocument 清空 //opera不起作用,使用Range.deleteContents











其他浏览器的一句话搞定doc.execCommand('InsertHTML', false, html);直接略过上述碰到的种种问题。


this.insertAtCursor1 = function(html) {
		if (isIE) {
			if (!cursel) {
				cursel = doc.selection.createRange();
		} else {
			var r = win.getSelection();
			if (r.toString().length) {
			if (!r.rangeCount) {
			} else {
				// opera
			var rg = r.getRangeAt(0);
			var tc = doc.createElement('span');
			tc.innerHTML = html;








this.newLine = function() {
		if (isIE) {
			if (!cursel) {
				cursel = doc.selection.createRange();
			cursel.text = '\n';
		} else {
			if (cox.isOpera || cox.isGecko) {
				var r = win.getSelection();
				if (r.toString().length) {
				if (!r.rangeCount) {
				} else {
					// opera
				var rg = r.getRangeAt(0);
				var tc = doc.createElement('br');
				 * opera下这样写反而到导致光标没有移动,不写倒是ok的,
				 * 火狐必须这样写,但是有个bug,如果开始什么都没有内容就换行会导致光标没换行(其实已经插入br了),
				 * 火狐这种写法还导致getText忽略了换行
				 * */
				if (cox.isGecko) {
			} else if (cox.isWebKit) {
				doc.execCommand('InsertText', false, '\n');

Continue reading 自己写html editor

https 跨域问题



这个页面有ajax请求test.ajax 好,一切ok.

然后你配置了tomcat https端口为8043,你再请求https://localhost:8043/abc/index.html


但是如果你在http://localhost:8080/abc/index.html里面请求https://localhost:8043/abc/test.ajax 那就是跨域了,会执行错误。



http://localhost:8080/abc/index.html 中将img.src付给https域,则会提示是否允许。


这就导致使用https 情况下new Image().src跨域的方式行不通了。

Continue reading https 跨域问题

【转】keytool - 密钥和证书管理工具




keytool - 密钥和证书管理工具:

管理由私钥和认证相关公钥的 X.509 证书链组成的密钥仓库(数据库)。还管理来自可信任实体的证书。


keytool [ 命令 ]


keytool 是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务。它还允许用户储存他们的通信对等者的公钥(以证书形式)。


keytool 将密钥和证书储存在一个所谓的密钥仓库中。缺省的密钥仓库实现将密钥仓库实现为一个文件。它用口令来保护私钥。

请注意:keytool工具完全取代了  JDK 1.1 中提供的 javakey 工具。新工具所提供的功能比 javakey 提供的多,包括能够用口令来保护密钥仓库和私钥,以及除了能够生成签名外还可以校验它们。新的密钥仓库体系结构取代了 javakey 所创建和管理的身份数据库。可以利用 - identitydb keytool 命令将信息从身份数据库导入密钥仓库。


密钥项 - 每项存放极为敏感的加密密钥信息,这种信息以一种受保护的格式储存以防止未授权的访问。通常,储存在这类项中的密钥是机密密钥,或是伴有用于认证相应公钥用的证书“链”的私钥。keytool只处理后一类型的项,即私钥及其关联的证书链。

可信任的证书项 - 每项包含一个属于另一团体的公钥证书。它之所以叫做“可信任的证书”,是因为密钥仓库的拥有者相信证书中的公钥确实属于证书“主体”(拥有者)识别的身份。证书签发人通过对证书签名来保证这点。

对所有的密钥仓库项(密钥项和可信任的证书项)的访问都要通过唯一的别名来进行。别名不区分大小写,即别名 SHECA sheca 指的是同一密钥仓库项。

当用 -genkey 命令来生成密钥对(公钥和私钥)或用 -import 命令来将证书或证书链加到可信任证书的清单中,以增加一个实体到密钥仓库中,必须指定了一个别名。后续 keytool 命令必须使用这一相同的别名来引用该实体。



    keytool -genkey -alias sheca –keypasss shecakeypasswd


这指定了一个初始口令“shecakeypasswd”,接下来的命令都要使用该口令才能访问与别名sheca 相关联的私钥。以后如果您想更改sheca的私钥口令,可用类似下述的命令:


    keytool -keypasswd -alias sheca -keypass shecakeypasswd -new newpass




每个 keytool 命令都有一个 -keystore 选项,用于指定 keytool 管理的密钥仓库的永久密钥仓库文件名称及其位置。缺省情况下,密钥仓库储存在用户宿主目录(由系统属性的“user.home”决定)中名为 .keystore 的文件中。在 Solaris 系统中 user.home”缺省为用户的宿主目录。

密钥仓库的创建,当用 -genkey-import -identitydb 命令向某个尚不存在的密钥仓库添加数据时,就创建了一个密钥仓库。

具体地说,如果在 -keystore 选项中指定了一个并不存在的密钥仓库,则该密钥仓库将被创建。如果不指定 -keystore 选项,则缺省密钥仓库将是宿主目录中名为 .keystore 的文件。如果该文件并不存在,则它将被创建。 包中提供的 KeyStore 类为访问和修改密钥仓库中的信息提供了相当固定的接口。可以有多个不同的具体实现,其中每个实现都是对某个特定类型的密钥仓库的具体实现。

Sun Microsystems 公司提供了一个内置的缺省实现。它利用名为“JKS 的专用密钥仓库类型(格式),将密钥仓库实现为一个文件。它用个人口令保护每个私钥,也用口令(可能为另一个口令)保护整个密钥仓库的完整性。

keytool允许用户指定任何注册了的加密服务提供者所提供的密钥对生成和签名算法。也就是说,各种命令中的 keyalg sigalg 选项必须得到提供者的实现的支持。缺省的密钥对生成算法是“DSA”。签名算法是从所涉及私钥的算法推导来的:如果所涉及的私钥是“DSA”类型,则缺省的签名算法为 SHA1withDSA”,如果所涉及的私钥是“RSA”类型,则缺省的签名算法为“MD5withRSA”。在生成 DSA 密钥对时,密钥大小的范围必须在 512 1024 位之间,且必须是 64 的倍数。缺省的密钥大小为 1024 位。

使用 keytool 可以显示、导入和导出证书。还可以产生自签名证书。keytool 目前处理 X.509 证书。


1X.509 证书:

X.509 标准规定了证书可以包含什么信息,并说明了记录信息的方法(数据格式)。除了签名外,所有 X.509 证书还包含以下数据:


识别用于该证书的 X.509 标准的版本,该版本影响证书中所能指定的信息。迄今为止,已定义的版本有三个。keytool 可导入和导出 v1v2 v3 版的证书。它只能生成 v1 版证书。


发放证书的实体有责任为证书指定序列号,以使其区别于该实体发放的其它证书。此信息用途很多。例如,如果某一证书被撤消,其序列号将放到证书撤消清单 (CRL) 中。


用于标识 CA 签名证书时所用的算法。


签名证书的实体的 X.500 特征名。它通常为一个 CA。使用该证书意味着信任签名该证书的实体。注意:有些情况下(例如根或顶层 CA 证书),签发人会签名自己的证书。




证书可以识别其公钥的实体名。此名称使用 X.500 标准,因此在Internet中应是唯一的。它是实体的 X.500 特征名 (DN),例如:


    CN=Java SHECA, OU=Java Software Division, O=Sun Microsystems Inc, C=US





证书中的所有数据均用两个名为 ASN.1/DER 的相关标准进行编码。抽象语法注释 1 (Abstract Syntax Notation 1) 描述数据。确定性编码规则 (Definite Encoding Rules) 描述储存和传输该数据的唯一方式。

Keytool使用-import -printcert 命令读入的证书可以是这种格式的编码或是二进制格式的编码。

缺省情况下,-export 命令将以二进制编码格式输出证书,但如果指定了 -rfc 选项,则将以可打印的编码格式输出证书。

缺省情况下,-list 命令打印证书的 MD5 指纹。而如果指定了 -v 选项,将以可读格式打印证书,如果指定了 -rfc 选项,将以可打印的编码格式输出证书。 在其可打印的编码格式中,已编码证书的起始行是:










keytool 可创建和管理密钥仓库的“密钥”项,每个密钥项都含有私钥和相关证书“链”。链中的第一个证书含有与私钥对应的公钥。

当第一次产生密钥时,链中只含有一个元素,即自签名证书。自签名证书是一个这样的证书:其签发人(签名人)与主体(证书所认证的公钥所属的实体)相同。当调用 -genkey 命令来生成新的公钥/私钥对时,它同时也把公钥打包进自签名证书中。

之后,当证书签名请求 (CSR)被生成并送至认证机构 (CA) 后,CA 的答复将被导入,证书链将取代自签名证书。在链的底部是认证主体公钥的CA 所发放的证书(答复)。链中下一个证书是用于认证 CA 公钥的证书。

在许多情况下,这是个自签名证书(即来自认证其自身公钥的 CA 的证书)且是链中的最后一个证书。在其它情况下,CA 也许将返回证书链。这种情况下,链中底部的证书是相同的(由 CA 签名的证书,对密钥项的公钥进行认证),但链中第二个证书是由不同的 CA 所签名的,对您向其发送 CSR CA 的公钥进行认证。然后,链中的下一个证书将是对第二个 CA 的公钥进行认证的证书,以此类推,直至到达自签名的“根”证书为止。因此,链中的每个证书(从第一个以后)都对链中前一个证书的签名人的公钥进行认证。

许多 CA 只返回所发放的证书,而不支持链,特别是当层次结构较简单时(无中介 CA)。这种情况下,必须用储存在密钥仓库中的可信任的证书信息来建立证书链。

另一种答复格式(由 PKCS#7 标准所定义)除了包含所签发的证书外,还支持证书链。两种答复格式都可由 keytool 处理。

顶层(根)CA 证书是自签名的。但是,对根公钥的信任并非来自根证书本身,而是来自报纸之类的其它来源。根 CA的公钥是广为人知的。它被储存在证书中的唯一原因是因为这是大多数工具所能理解的格式,因此这种情况下的证书只是作为一种传输根 CA 的公钥用的“交通工具”。在将根 CA 证书加到您的密钥仓库中之前,应该先对它进行查看(用 - printcert 选项)并将所显示的指纹与已知的指纹(从报纸、根 CA 的网页等中获取)进行比较。


要从一个文件中导入某个证书,可用 -import 命令,如下所示:


    keytool -import -alias sheca -file jcertfile.cer


此样本命令导入文件 jcertfile.cer 中的证书并将其存储在由别名sheca标识的密钥仓库项中。


1、  为将其添加到可信任的证书清单中;

2、  为导入因向 CA 提交证书签名请求而收到的来自该 CA 的认证答复。

-alias  选项的值指明要进行何种类型的导入。如果数据库中存在别名,且该别名标识具有私钥的项,则将假定您要导入认证答复。keytool 将检查认证答复中的公钥是否与用别名储存的私钥相匹配,如果两者不同,则程序退出。如果别名标识另一种类型的密钥仓库项,则不导入该证书。如果该别名不存在,则它将被创建并与导入的证书关联。




先查看一下(用  -printcert 命令,或用不带 -noprompt 选项的 -import 命令),确保所显示的证书指纹与所预计的相匹配。例如,假设某人给您送来或用电子邮件发来一个证书,您将它放在名为 /tmp/cert 的文件中。在将它加到可信任证书的清单中之前,可通过执行 - printcert 命令来查看它的指纹,如下所示:


  keytool -printcert -file /tmp/cert


    Owner: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll


    Issuer: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll


    Serial Number: 59092b58


    Valid from: Thu Sep 25 18:01:13 PDT 2007 until: Wed Dec 24 17:01:13 PST 2007


    Certificate Fingerprints:





然后给向您发送证书的人打电话或用其它方式联系,将您将您所看到的指纹与他们所提供的比较。只有两者相等才可保证证书在传送途中没有被其它人(例如,攻击者)的证书所更换。如果发生了这样的攻击,而您未检查证书即将其导入,您就会信任攻击者所签名的任何东西(例如,一个含有恶意类文件的 JAR 文件)。

并不要求在导入证书前执行 -printcert 命令,因为在将证书添加到密钥仓库中可信任证书的清单中之前,-import 命令将会打印出该证书的信息,并提示您进行校验。这时,您可选择中止导入操作。但是注意,只有在调用不带 -noprompt 选项的 -import 命令时才能这样做。如果给出了 -noprompt 选项,则不存在与用户的交互


要将证书导出到文件中,请用 -export 命令,如下所示:


    keytool -export -alias sheca -file shecacertfile.cer


该样本命令将 jane 的证书导出到文件 shecacertfile.cer 中。也就是说,如果 sheca 是某个密钥项的别名,该命令将导出该密钥仓库项中所含证书链底部的证书。这是认证sheca 的公钥用的证书。相反如果sheca是某个可信任证书项的别名,则导出的是该可信任的证书。


要打印某个密钥仓库项的内容,请用 -list 命令,如下所示:


    keytool -list -alias joe




    keytool -list



要显示储存在文件中的证书的内容,请用 -printcert 命令,如下所示:


    keytool -printcert -file certfile.cer


这将打印储存在文件 certfile.cer 中的有关证书的信息。


要生成自签名证书,请用 -selfcert 命令,如下所示:


    keytool -selfcert -alias shecaNew -keypass sheca123


      -dname "cn=James, ou=SHECA, o=Soft, c=CN"




1、所有的命令和选项名之前都有减号 (-)



4、选项周围的花括号通常表示如果在命令行中没有指定该选项,则使用缺省值。花括号还用在 -v-rfc -J 选项周围,这些选项只有在命令行中出现时才有意义(也就是说,它们没有任何缺省值,不然就是不存在该选项)。

5、选项周围的方括号表示如果在命令行中没有指定该选项,则用户将得到要求输入其值的提示。(对于 -keypass 选项,如果在命令行中没有指定该选项,keytool 将先是尝试用密钥仓库口令来访问私钥,如果失败,再提示您输入私钥口令。)

6、斜体项(选项)代表必须提供实际值。例如,下面是 -printcert 命令的格式:


  keytool -printcert {-file cert_file} {-v}


当指定 -printcert 命令时,请用实际文件名来替代 cert_file,如下所示:


  keytool -printcert -file VScert.cer




-help 命令是缺省命令。因此,命令行






  keytool -help






-alias "mykey"


-keyalg "DSA"


-keysize 1024


-validity 90


-keystore 用户宿主目录中名为 .keystore 的文件

-file 读时为标准输入,写时为标准输出

签名算法(-sigalg 选项)是由所涉及私钥的算法推导而来的:如果所涉及的私钥是“DSA”类型,则 -sigalg 选项将缺省为“带 DSA SHA1”,如果所涉及的私钥是“RSA”类型,则 -sigalg 选项将缺省为“带 RSA MD5”。

-v 选项可出现在除 -help 之外的所有命令中。如果出现该选项,表示处在“长格式”模式下;将输出详细的证书信息。

-javaoption  选项也可在任何命令中出现。如果出现该选项,则所指定的 javaoption 字符串将被直接传给 Java 解释器。(keytool 实际上是解释器周围的一个 wrapper”。) 该选项不应含有任何空格。它有助于调整执行环境或内存使用。要获得可用的解释器选项的清单,可在命令行键入  java -h java -X


-storetype storetype

此限定符指定将被实例化的密钥仓库类型。缺省的密钥仓库类型是安全属性文件中“keystore.type”属性值所指定的那个类型,由 中的静态方法 getDefaultType 返回。

-keystore keystore

密钥仓库(数据库文件)的位置。缺省情况下,密钥仓库指的是用户宿主目录的 .keystore 文件,它是由“user.home”的系统属性确定的。在 Solaris 系统中,“user.home”缺省为用户宿主目录。

-storepass storepass


storepass 的长度必须至少为 6 个字符。所有访问密钥仓库内容的命令都必须提供这一选项。对于这些命令,如果没有给出 -storepass 选项,则用户将得到要求输入该选项的提示。




-genkey {-alias alias} {-keyalg keyalg} {-keysize keysize} {-sigalg sigalg} [-dname dname] [-keypass keypass] {-validity valDays} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}

该命令产生密钥对(公钥和与之关联的私钥)。将公钥打包进 X.509 v1 的自签名证书中,该证书以单元素证书链的形式储存。该证书链和私钥将储存于 alias 所标识的新密钥仓库项中。

keyalg 指定了用于生成密钥对的算法,而 keysize 指定要生成的每个密钥的大小。sigalg 指定签名自签名证书所用的算法;这一算法必须与 keyalg 兼容。参见支持的算法和密钥大小。

dname 指定与 alias 关联的 X.500 特征名,并用作自签名证书中的 issuer subject 域。如果在命令行中没有提供特征名,用户将得到要求输入该信息的提示。

keypass  是口令,用来保护所生成密钥对中的私钥。如果没有提供口令,用户将得到要求输入口令的提示。如果在提示符下按 RETURN 键,则密钥口令将被设置为与密钥仓库所用的口令相同。keypass 的长度必须至少为 6 个字符。使用口令时必须小心 - 参见 与口令有关的警告。

valDays 指定证书的有效期。


-import {-alias alias} {-file cert_file} [-keypass keypass] {-noprompt} {-trustcacerts} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}

从文件 cert_file 中读取证书或证书链(后者在 PKCS#7 格式的答复所给出)并将其储存在 alias 所标识的密钥仓库项中。如果没有给出文件,则从标准输入设备中读取证书或 PKCS#7 答复。keytool 可导入 X.509 v1v2 v3 的证书以及由该类证书所组成的  PKCS#7 格式的证书链。要导入的数据必须是二进制编码格式或 Internet RFC 1421 标准所定义的可打印的编码格式(也称  Base64 编码)。在后一种情况下,编码必须用以“-----BEGIN”开头的字符串开始,用以“-----END”结尾的字符串来结束。

当导入新的可信任证书时,密钥仓库中还没有 alias。在把证书添加到密钥仓库中之前,keytool 将尝试用密钥仓库中已有的可信任证书来构造从该证书到自签名证书(属于根 CA)的信任链,以对证书进行校验。

如果指定了 -trustcacerts 选项,则将为该信任链考虑其它证书,即考虑名为“cacerts”的文件中的证书,该文件位于 JDK 安全属性目录 java.home\lib\security 中,其中 java.home JDK 安装目录。“cacerts”文件代表含有 CA 证书的系统范围的密钥仓库。通过指定密钥仓库类型为“jks”,系统管理员可用 keytool 来配置和管理该文件。“cacerts”密钥仓库文件发送时附有五个 VeriSign CA 证书,其 X.500 特征名如下:


1. OU=Class 1 Public Primary Certification Authority, O="VeriSign, Inc.",




2. OU=Class 2 Public Primary Certification Authority, O="VeriSign,


Inc.", C=US


3. OU=Class 3 Public Primary Certification Authority,


O="VeriSign, Inc.", C=US


4. OU=Class 4 Public Primary Certification


Authority, O="VeriSign, Inc.", C=US


5. OU=Secure Server Certification


Authority, O="RSA Data Security, Inc.", C=US


cacerts”密钥仓库文件的初始口令为“changeit 。系统管理员在安装 JDK 后,就应该立即更改这个口令以及该文件的缺省访问权限。

如果 keytool 无法建立从要导入的证书到自签名证书的信任路径(利用密钥仓库或“cacerts”文件),则打印出该证书的信息,而用户将得到要求校验的提示,例如,系统将通知用户通过比较显示出的指纹和得自其它(可信任的)信息来源的指纹来进行校验,信息来源可能是证书拥有者本人。在将证书作为一个“可信任”证书导入之前,要十分小心,务必保证该证书是有效的!然后,用户可以选择中止导入操作。但是,如果给了 -noprompt 选项,则不会有与用户的交互。

当导入认证答复时,该认证答复将用密钥仓库中可信任的证书来确认,有时也使用在“cacerts”密钥仓库文件中配置的证书(如果指定了 -trustcacerts 选项)。

如果答复是一个 X.509 证书,keytool 将尝试建立信任链,以该认证答复为头,以属于根 CA 的自签名证书为尾。该认证答复和用于认证该认证答复的证书层次形成了 alias 的新证书链。

如果答复是 PKCS#7 格式的证书链,则该链应首先被排序(用户证书在最前面,自签名的根 CA 证书在最后面),然后 keytool 尝试将答复中的根 CA 证书与密钥仓库或“cacerts”密钥仓库文件(如果指定了 -trustcacerts 选项)中的任何可信任证书进行匹配。如果找不到匹配,则打印出该根 CA 证书的信息,而用户将得到要求校验它的提示,例如,系统将通知用户通过比较显示出的指纹和得自其它(可信任的)信息来源的指纹来进行校验,信息来源可能是证书拥有者本人。因此,用户可以选择中止导入操作。但是,如果给了 -noprompt 选项,则不会有与用户的交互。

alias  的新证书链将取代与该项关联的旧证书链。只有提供了有效的 keypass,即提供了用于保护该项的私钥的口令时,旧链才可被取代。如果没有提供口令,而且私钥口令与密钥仓库口令不同,用户将得到要求输入口令的提示。


-selfcert {-alias alias} {-sigalg sigalg} {-dname dname} {-validity valDays} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}

利用密钥仓库信息(包括与 alias 关联的私钥和公钥)产生 X.509 v1 自签名证书。如果在命令行提供了 dname,它将同时用作该证书的签发人和主体的 X.500 特征名。否则,将使用与 alias 关联的 X.500 特征名(位于其现有证书链底部)。

所生成的证书作为 alias 所标识的密钥仓库项中的单元素证书链来存储,它将取代现有的证书链。

sigalg 指定签名证书用的算法。参见支持的算法和密钥大小。

要访问私钥,必须提供正确的口令,因为私钥在密钥仓库中是受口令保护的。如果在命令行中没有提供 keypass,且私钥口令与保护密钥仓库完整性所用的口令不同,则用户将得到要求输入该口令的提示。

valDays 指定证书的有效期。

-identitydb {-file idb_file} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}

idb_file 文件中读取 JDK 1.1.x 格式的身份数据库,并将它的项加到密钥仓库中。如果没有给出文件名,则从标准输入设备中读取身份数据库。如果不存在密钥仓库,则创建它。


所有可信任身份的私钥都将在相同的口令 storepass 下得到加密。该口令与保护密钥仓库完整性所用的口令相同。用户随后可用 keytool 命令选项“-keypasswd”来对各私钥赋予单独的口令。




-certreq {-alias alias} {-sigalg sigalg} {-file certreq_file} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}


生成 PKCS#10 格式的证书签名请求 (CSR)

CSR 用来发送给认证机构 (CA)CA 对认证请求者进行认证(通常是离线的),并返回证书或证书链,以取代密钥仓库中现有的证书链(该证书链最初只含有自签名证书)。

私钥和与 alias 关联的 X.500 特征名用于创建 PKCS#10 证书请求。要访问私钥,必须提供正确的口令,因为私钥在库中是受口令保护的。如果在命令行没有提供 keypass,且私钥口令与保护密钥仓库完整性所用的口令不同,则用户将得到要求输入口令的提示。

sigalg 指定签名 CSR 时用的算法。参见支持的算法和密钥大小。

CSR 存储在文件 certreq_file 中。如果没有给出文件名,CSR 将被输出到标准输出设备中。

import 命令来导入 CA 所返回的答复。


-export {-alias alias} {-file cert_file} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-rfc} {-v} {-Jjavaoption}

从密钥仓库中读取与 alias 关联的证书,并将其储存在文件 cert_file 中。


缺省情况下,证书被输出为二进制编码格式,但如果指定了 -rfc 选项,则将被输出为 Internet RFC 1421 标准中定义的可打印格式。

如果 alias 引用的是可信任证书,则该证书将被输出。否则,alias 引用的是含有相关证书链的密钥项。在这种情况下,链中的第一个证书将被返回。该证书对由 alias 所指定的实体的公钥进行认证。



-list {-alias alias} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v | -rfc} {-Jjavaoption}


打印(到标准输出设备中)alias 所标识的密钥仓库项的内容。如果没有指定别名,则将打印整个密钥仓库的内容。

缺省情况下,该命令打印证书的 MD5 指纹。如果指定了 -v 选项,证书将以可读格式打印,同时包含拥有者、签发人和序列号等附加信息。如果指定了??-rfc 选项,证书将以 Internet RFC 1421 标准所定义的可打印的编码格式打印。

不能同时指定 -v -rfc 两个选项。

-printcert {-file cert_file} {-v} {-Jjavaoption}

从文件 cert_file 中读取证书将以可读格式打印其内容。如果没有给出文件名,则从标准输入设备中读取证书。

证书可以是用二进制编码或 Internet RFC 1421 标准所定义的可打印编码格式。





-keyclone {-alias alias} [-dest dest_alias] [-keypass keypass] [-new new_keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}



原始项由 alias (如果没有提供别名,则其值缺省为“mykey”)标识。新(目标)项由 dest_alias 标识。如果没有在命令行中提供目标别名,用户将得到要求输入该信息的提示。

如果私钥口令与密钥仓库口令不同,那么,只有提供了有效的 keypass 时该项才能被复制。keypass 是用于保护与 alias 关联的私钥的口令。如果没有在命令行提供密钥口令,且私钥口令与密钥仓库口令不同,用户将得到要求输入口令的提示。如果愿意,可用不同的口令来保护复制项中的私钥。如果没有在命令行提供 -new 选项,用户将得到提示要求输入新项的口令(可以选择让该口令与被复制项的私钥所用的口令相同)。



-storepasswd [-new new_storepass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}


更改保护密钥仓库内容的完整性所用的口令。新口令为 new_storepass,其长度必须至少是 6 个字符。


-keypasswd {-alias alias} [-keypass old_keypass] [-new new_keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}


把保护 alias 所标识的私钥的口令从 old_keypass 更改为 new_keypass

如果没有在命令行提供 keypass 选项,且私钥口令与密钥仓库口令不同,则用户将得到要求输入该口令的提示。

如果没有在命令行给出 -new 选项,则用户将得到要求输入新口令的提示。


-delete [-alias alias] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-v} {-Jjavaoption}


从密钥仓库中删除 alias 所标识的项。如果没有在命令行上提供别名,则用户将得到要求输入别名的提示。









    keytool -genkey -dname "cn=Mark Jones, ou=JavaSoft, o=Sun, c=US"


      -alias business -keypass kpi135 -keystore /working/mykeystore


      -storepass ab987c -validity 180



该命令将在 C 盘的“working”目录(假设它还不存在)中创建名为“mykeystore”的密钥仓库,并赋予它口令“ab987c”。它将为实体生成公钥/私钥对,该实体的“特征名”为:常用名“Mark Jones”、组织单位“JavaSoft”、组织“Sun”和两个字母的国家代码 US”。它使用缺省的“DSA”密钥生成算法来创建密钥,两个密钥(公钥与私钥)的长度都是 1024 位。

它创建自签名证书(使用缺省的“带 DSA SHA1”签名算法),该证书包括公钥和特征名信息。该证书的有效期为 180 天,且与别名“business”所代表的密钥仓库项关联。私钥被赋予口令“kpi135”。



    keytool -genkey


这种情况下,将创建一个具有别名“mykey”的密钥仓库项,它含有新生成的密钥对和有效期为 90 天的证书。该项被放在您的宿主目录下一个名为 .keystore”的密钥仓库中(如果该密钥仓库并不存在,则将创建它)。您将得到要求输入特征名信息、密钥仓库口令和私钥口令的提示。

其余示例假设您执行了未指定选项的 -genkey 命令,且用上述第一个 -genkey 命令中给出的值来回答提示要求(私钥口令为“kpi135”等等)。


目前为止我们所具有的就是自签名证书。证书如果由认证机构 (CA) 签名,将更有可能得到别人的信任。要得到这样的签名,首先要用以下命令生成证书签名请求 (CSR)


    keytool -certreq -file MarkJ.csr


这将为缺省别名“mykey”所标识的实体生成 CSR,并将此请求放在名为“MarkJ.csr”的文件中。将此文件提交给某个 CA(例如  VeriSign, Inc.)。该 CA 将对您这个请求者进行认证(通常是离线的),然后返回它们所签名的证书,用于认证您的公钥。(某些情况下,它们实际上将返回证书链,链中每个证书都认证前一个证书的签名人的公钥。)


3、导入 CA 的证书

自签名证书必须用证书链代替,链中的每个证书都认证前一个证书的签名人的公钥,直到“根”CA 为止。

在导入 CA 的答复之前,在您的密钥仓库中或 cacerts 密钥仓库文件(如导入命令中所述)中需要有一个或多个“可信任”证书:

如果该认证答复是个证书链,您只需要链中最顶部的证书(即用于认证根 CA 的公钥的“根” CA 证书)。

如果该认证答复是单个证书,您需要发放 CA(即签名该证书的认证机构)的证书,如果此证书不是自签名的,则需其签名人的证书,以此类推,直到自签名的“根” CA 证书为止。

cacerts 密钥仓库文件发送时附有五个 VeriSign CA 证书,因此您可能并不需要导入 VeriSign 证书以作为密钥仓库中的可信任证书。但如果您请求由另一个 CA 签名的证书,而认证该 CA 的公钥的证书未被加到“cacerts”中,则您需要将来自该 CA 的证书作为“可信任证书”导入。

来自 CA 的证书通常是自签名的或是由另一个 CA 签名的(这种情况下您还需要认证该 CA 的公钥的证书)。假设 ABC, Inc. 公司是 CA,而您从该公司获得一个声称是自签名证书的名为“ABCCA.cer”的文件,它用于认证该 CA 的公钥。

在将证书作为一个“可信任”证书导入之前,要十分小心,务必保证该证书是有效的!先查看一下(用 keytool -printcert 命令,或用不带  -noprompt 选项的 keytool -import 命令)以确保所显示的证书指纹与所预计的相匹配。然后可以给发送证书的人打电话,将您所看到的指纹与他们所提供的(或安全公钥储存库所显示的)进行比较。只有两者相等才可保证证书在传送途中没有被其它人(例如,攻击者)的证书所更换。如果发生了这样的攻击,而您未检查证书即将其导入,那么您就会信任攻击者所签名的任何东西。



    keytool -import -alias abc -file ABCCA.cer



导入来自 CA 的认证答复

一旦导入了用于认证 CA(该 CA 是您将证书签名请求送往之处)公钥的证书后,或在“cacerts”文件中已有这种证书时,就可以导入该认证答复,从而用证书链取代您的自签名证书。如果 CA 的答复是证书链,则该链是 CA 响应您的请求而返回的证书链;如果 CA 的答复是一个证书,则该链是用认证答复和可信任证书建立的证书链,这些可信任证书是密钥仓库(您要将认证答复导入之处)或“cacerts”密钥仓库文件中已有的。

例如,假设您将证书签名请求送往 VeriSign。您可用以下命令来导入认证答复,该命令假定所返回的证书名为“VSMarkJ.cer”:


    keytool -import -trustcacerts -file VSMarkJ.cer



认证签名的一种方法是先将您的公钥证书作为“可信任”项导入它们的密钥仓库中。您可以将证书导出并将其提供给客户机。例如,假设项的别名为“mykey”,您可以用以下命令将您的证书导出到名为 MJ.cer 的文件中:


    keytool -export -alias mykey -file MJ.cer



假设,譬如说因为您换了部门或搬到另一个城市去了而改变了您的特征名。如果愿意,您仍然可以使用您先前使用的公钥/私钥对而只对特征名进行更新。例如,假设您的名字叫 Susan Miller,并用别名 sMiller 和以下的特征名创建了初始密钥项:


  "cn=Susan Miller, ou=Finance Department, o=BlueSoft, c=us"




    keytool -keyclone -alias sMiller -dest sMillerNew




    keytool -selfcert -alias sMillerNew


      -dname "cn=Susan Miller, ou=Accounting Department, o=BlueSoft, c=us"




    keytool -certreq -alias sMillerNew


当您得到 CA 认证答复后,将其导入:


    keytool -import -alias sMillerNew -file VSSMillerNew.cer




    keytool -delete -alias sMiller

Continue reading 【转】keytool - 密钥和证书管理工具




由于配置CAS的单点登陆系统,需要先配置Tomcat 的SSL, 在配置tomcat的SSL过程中,我配置的版本是tomcat5.5.20,参考了很多资料,但发现一直不行,后来我换到了5.5.9,结果非常顺利,我于是换了总共4个主要版本,发现SSL的配置还真有些不同,现在我将这些配置记录下来,供下次参考。





1. 生成 server key :[生成keystore文件]


keytool -genkey -alias tomcat -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore -validity 3600

用户名输入域名,如localhost(开发或测试用)或hostname.domainname(用户拥有的域名),其它全部以 enter 跳过,最后确认,此时会在%TOMCAT_HOME%下生成server.keystore 文件。


注:参数 -validity 指证书的有效期(天),缺省有效期很短,只有90天。

2.  将证书导入的JDK的证书信任库中:

这步对于Tomcat的SSL配置不是必须,但对于CAS SSO是必须的,否则会出现如下错误 Unable to validate ProxyTicketValidator。。。


keytool -export -trustcacerts -alias tomcat -file server.cer -keystore  server.keystore -storepass changeit

[从server.keystore中导出server.cer ,这里的密码是server.keystore的密码]

keytool -import -trustcacerts -alias tomcat -file server.cer -keystore  %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit

[将server.cer 导入keystore文件cacerts中 ,cacerts是jre自带的keystore文件,注意这里的密码是cacerts的密码,原始密码是changeit]



keytool -list -v -keystore D:/sdks/jdk1.5.0_11/jre/lib/security/cacerts

keytool -delete -trustcacerts -alias tomcat  -keystore  D:/sdks/jdk1.5.0_11/jre/lib/security/cacerts -storepass changeit

3.  配置TOMCAT :


xml 代码

将之后的那段的注释去掉,并加上 keystorePass及keystoreFile属性。



xml 代码

  2.    <Connector className="org.apache.coyote.tomcat4.CoyoteConnector" 
  3.            port="8443" enableLookups="true" scheme="https" secure="true" 
  4.            acceptCount="100" 
  5.            useURIValidationHack="false" disableUploadTimeout="true" 
  6.            clientAuth="false" sslProtocol="TLS"   
  7.            keystoreFile="server.keystore"   
  8.            keystorePass="changeit"/> 


xml 代码

  1. <Connector port="8443" maxHttpHeaderSize="8192"
  2. maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
  3. enableLookups="false" disableUploadTimeout="true"
  4. acceptCount="100" scheme="https" secure="true"
  5. clientAuth="false" sslProtocol="TLS"
  6. keystoreFile="server.keystore"
  7. keystorePass="changeit"/>

xml 代码

  1. <Connector protocol="org.apache.coyote.http11.Http11Protocol"
  2. port="8443" maxHttpHeaderSize="8192"
  3. maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
  4. enableLookups="false" disableUploadTimeout="true"
  5. acceptCount="100" scheme="https" secure="true"
  6. clientAuth="false" sslProtocol="TLS"
  7. keystoreFile="server.keystore"
  8. keystorePass="changeit"/>

xml 代码

  1. <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
  2. port="8443" minSpareThreads="5" maxSpareThreads="75"
  3. enableLookups="true" disableUploadTimeout="true"
  4. acceptCount="100" maxThreads="200"
  5. scheme="https" secure="true" SSLEnabled="true"
  6. clientAuth="false" sslProtocol="TLS"
  7. keystoreFile="D:/tools/apache-tomcat-6.0.10/server.keystore"
  8. keystorePass="changeit"/>



访问 https://localhost:8443/

<connector protocol="org.apache.coyote.http11.Http11NioProtocol"></connector>

Continue reading 【转】给Tomcat配置HTTPS访问

it-e-42 Algorithm Design and Implementation

This course introduces a set of fundamental design principles and problem-solving techniques
for the construction and implementation of computer algorithms. Problem solutions are developed
in a design language such as Pseudocode and then coded in a high-level structured programming
language. (Consult the Computer Science Department for the language currently in use.) Topics
such as problem specification, top-down design with stepwise refinement, standard data types,
control structures, subprograms, modular design, and parameter passing are presented through a
study of specific example algorithms. Style, documentation, solution robustness, and conformance
with specifications are emphasized throughout.
Prerequisites: High school algebra I & II.

The purpose of this course is to present a coherent set of tools and techniques for the
development of computer solutions to simple problems in data manipulation and report
generation. Upon completion of the course, a student should be able to: analyze a problem
statement for completeness and clarity; use the method of top-down, modular, structured design
to develop a hierarchy chart (structure chart) and a set of Pseudocode modules for a problem
solution; convert this solution into source code in the designated high-level language in
accordance with a well-defined set of style rules; debug and test the program; and provide clear
documentation for the result.

the "problem-solving universe"
operational definition of computer (specifically, electronic digital stored-program
components of a typical computer
fundamental computer capabilities (read, write, store, compute, compare)
formulating precise specifications for a problem and its solution
preconditions and post conditions

specification of user requirements in measurable terms
tools for algorithm development
algorithm design languages (Pseudocode, flowcharts)
top-down design and stepwise refinement (including contrast with bottom-up
structure charts (hierarchy charts)
subprograms (procedures, functions) and the modular design of algorithms
standard control structures:
sequence, decision, loop (pre-test, post-test, count- controlled), module
nested control structures
decision tables, decision trees
identifiers, variables, constants, expressions
typing and structuring of data
standard data types:
numeric (integer vs. real)
character, character string
file type (for sequential text files)
record types
array types
primitive data structures:
simple variables
record variables
character strings
some common algorithmic techniques
the Initialize/Process/Terminate (IPT) paradigm
file operations (create, open, close, read, write)
sequential processing of data records
end-of-file testing
report generation (headers, footers, page breaks, simple control breaks)

use of counters and accumulators
numeric computations (evaluating formulas, generating sequences, printing
exchanging (swapping) data values
complex decisions and branching
testing and validating data
use of 'flag' variables
finding maximum and minimum values
array manipulations (filling, summing, searching, printing)
uses of record variables
communication between modules:
formal parameters, arguments, parameter passing, inheritance
coding algorithms in a high-level language
overall structure of a program (including stylistic layout)
internal and external documentation
nesting of procedures and functions
declarations, formal parameter lists
file variables and file operations
input/output (keyboard and file)
translation of standard control structures
arithmetic expressions
assignment statements, type compatibility
boolean expressions
implementing an algorithm on the computer
transcribing a pseudocode algorithm into a programming language
log-in procedures, customizing the account
creating a source file
compiling the program; compilation errors
generation of test data
executing the program; run-time (execution) errors


1, stepwise  ['step,waiz]
adv. 逐步地;阶梯式地

2, clarity  ['klæriti]
n. 清楚,透明

3, refinement  [ri'fainmənt]
n. 精致,高尚,精巧

4, arithmetic  [ə'riθmətik, ,æriθ'metik]
n. 算术,算法

Continue reading it-e-42 Algorithm Design and Implementation

it-e-41 Some Rules for Well-drawn Flow Charts

Well-drawn flow charts are easy to read. Here are a few rules for well-drawn flow charts:
Every flowchart has a START symbol and a STOP symbol.
The flow of sequence is generally from the top of the page to the bottom of the page. This
can vary with loops which need to flow back to an entry point.
Use arrow-heads on connectors where flow direction may not be obvious.
There is only one flow chart per page.
A page should have a page number and a title.
A flow chart on one page should not break and jump to another page.
A flow chart should have no more than around 15 symbols (not including START and

Continue reading it-e-41 Some Rules for Well-drawn Flow Charts


Total views.

© 2013 - 2019. All rights reserved.

Powered by Hydejack v6.6.1