?? crypt in pure tcl.mht
字號:
From: =?gb2312?B?08kgV2luZG93cyBJbnRlcm5ldCBFeHBsb3JlciA3ILGjtOY=?=
Subject: crypt in pure tcl
Date: Fri, 29 Feb 2008 00:37:54 +0800
MIME-Version: 1.0
Content-Type: multipart/related;
type="text/html";
boundary="----=_NextPart_000_008E_01C87A6B.52501B10"
X-MimeOLE: Produced By Microsoft MimeOLE V6.0.6000.16545
這是 MIME 格式的多方郵件。
------=_NextPart_000_008E_01C87A6B.52501B10
Content-Type: text/html;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://wiki.tcl.tk/1070
=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" =
"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML lang=3Den><HEAD><TITLE>crypt in pure tcl</TITLE>
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
<STYLE type=3Dtext/css media=3Dall>@import url( /wikit.css );
</STYLE>
<LINK title=3DRSS href=3D"/rss.xml" type=3Dapplication/rss+xml =
rel=3Dalternate><!--[if lte IE 6]>=0A=
<style type=3D'text/css' media=3D'all'>@import 'ie6.css';</style>=0A=
<![endif]--><!--[if gte IE 7]>
<STYLE type=3Dtext/css media=3Dall>@import url( ie7.css );
</STYLE>
<![endif]-->
<SCRIPT type=3Dtext/javascript>=0A=
function init() {=0A=
// quit if this function has already been called=0A=
if (arguments.callee.done) return;=0A=
=0A=
// flag this function so we don't do the same thing twice=0A=
arguments.callee.done =3D true;=0A=
=0A=
try {=0A=
checkTOC();=0A=
} catch (err) {=0A=
/* nothing */=0A=
}=0A=
};=0A=
=0A=
/* for Mozilla */=0A=
if (document.addEventListener) {=0A=
document.addEventListener("DOMContentLoaded", init, false);=0A=
}=0A=
=0A=
/* for Internet Explorer */=0A=
/*@cc_on @*/=0A=
/*@if (@_win32)=0A=
document.write("<script defer src=3Die_onload.js><\/script>");=0A=
/*@end @*/=0A=
=0A=
/* for other browsers */=0A=
window.onload =3D init;=0A=
</SCRIPT>
<META content=3D"MSHTML 6.00.6000.16609" name=3DGENERATOR></HEAD>
<BODY>
<DIV class=3Dcontainer>
<DIV class=3Dheader>
<DIV class=3Dlogo><A class=3Dlogo =
href=3D"http://wiki.tcl.tk/">wiki.tcl.tk</A> </DIV>
<DIV class=3Dtitle id=3Dtitle><A title=3D"click to see 5 references to =
this page"=20
href=3D"http://wiki.tcl.tk/_ref/1070">crypt in pure tcl</A></DIV>
<DIV class=3Dupdated id=3Dupdated>Updated 2005-09-01 01:02:17 <A =
class=3Ddelta=20
href=3D"http://wiki.tcl.tk/_diff/1070#diff0">=E2=96=B2</A></DIV></DIV>
<DIV id=3Dwrapper>
<DIV id=3Dcontent>
<P>From time to time it seems someone posts on comp.lang.tcl looking for =
a <A=20
href=3D"http://wiki.tcl.tk/9447">crypt</A> function. The tclhttpd =
package has a=20
C-implementation. As an experiment I decided to convert a C crypt =
function to=20
Tcl.</P>
<P>I used the C source code to AOLserver's ns_crypt function [<A=20
href=3D"http://aolserver.com/source/display.adp?file=3D%2fdci%2fservers%2=
faolservercom%2fservers%2faolservercom%2fpages%2fsource%2fcurrent%2fnsd%2=
fcrypt%2ec"=20
rel=3Dnofollow>1</A>] as a reference.</P>
<P>On my aging P-133 my original Tcl version took over 36 seconds to =
encrypt a=20
single password. After placing braces around each expression to be =
evaluated by=20
<A href=3D"http://wiki.tcl.tk/583">expr</A> performance sped up to about =
4.0/4.1=20
seconds on average. In comparison, on the same computer, the C version =
from the=20
tclhttpd package runs in 713 microseconds. Still, I suppose there may be =
instances where a <A href=3D"http://wiki.tcl.tk/2393">pure-Tcl</A> =
version is=20
desirable, and in a few years processors will be fast enough that maybe =
it won't=20
make a noticeable difference. :-)</P>
<P>-- <I>Michael A. Cleverly</I> (23/Nov/2000)</P>
<P><A href=3D"http://wiki.tcl.tk/1767">AK</A> 19 Jun 2003: The license =
of=20
AOLserver [<A href=3D"http://www.aolserver.com/" rel=3Dnofollow>2</A>] =
is the=20
Mozilla Public License [<A href=3D"http://www.aolserver.com/license/"=20
rel=3Dnofollow>3</A>], and not <A =
href=3D"http://wiki.tcl.tk/1863">GPL</A>. <A=20
href=3D"http://wiki.tcl.tk/3676">MC</A>: In deed it is, though an offer =
of=20
dual-licensing is made (see Exhibit A of the AOLserver license). The MPL =
is more=20
compatible with the Tcl license obviously.</P>
<P>On my PIII notebook under 8.4 this now takes 0.6 s to encrypt a =
single=20
password. -- SC (August 2001)</P>
<P><I>Vince</I> -- I notice that most of the arrays here are actually =
used like=20
C arrays $IP(0), $IP(1), etc. Wouldn't the code be faster if those were =
changed=20
to list accesses? i.e. instead of:</P><PRE> array set IP { 0 58 1 50 =
... }
foo $IP($i)</PRE>
<P>use:</P><PRE> set IP [list 58 50 42 ...]
foo [lindex $IP $i]</PRE>
<P>I would be interested to hear how much of a difference it makes.</P>
<P><A href=3D"http://wiki.tcl.tk/2461">BBH</A> - (23 Jan 2001) Actually =
accessing=20
a single element is faster via array than list, (on my machine 3usec vs. =
5usec)=20
and setting is even more so.</P>
<P>compare</P><PRE> set ary($idx) [expr {$ary($idx2) * 3}]</PRE>
<P>with</P><PRE> set lst [lreplace $lst $idx $idx [expr {[lindex $lst =
$idx2] *3}]]</PRE>
<P>much less readable and in my test about 2.5 times slower</P>
<P><A href=3D"http://wiki.tcl.tk/2234">DGP</A> - ...but how about using =
[lset] (in=20
Tcl 8.4) ?!</P>
<P><A href=3D"http://wiki.tcl.tk/3676">MC</A> 20 Jun 2003: I've =
rewritten it to=20
use [lset] (see below). Seems to run 40-45% faster.</P>
<P><A href=3D"http://wiki.tcl.tk/1900">PT</A> 20 Jun 2003: This seems =
nice and=20
quite fast (0.2 sec per iteration on a PIII 800). However there are 3 =
NUL=20
characters on the end of my string.</P><PRE> perl -e 'print =
length(crypt("secret", "az"));'</PRE>
<P>gives 13 while</P><PRE> set c [crypt8.4 secret az]
string length $c</PRE>
<P>gives 16. The crypt strings are identical apart from the 3 NUL =
suffix.</P>
<P>Are we going to put this into tcllib one day? Or is the license=20
incompatible?</P>
<P><A href=3D"http://wiki.tcl.tk/3676">MC</A> 20 Jun 2003: Fixed the =
extraneous=20
null characters on the end. I pre-allocated too many elements in iobuf =
(since <A=20
href=3D"http://wiki.tcl.tk/2556">lset</A> can't create new =
elements).</P>
<HR>
<PRE> proc crypt {password salt} {
array set IP {
0 58 1 50 2 42 3 34 4 26 5 18 6 10 7 2
8 60 9 52 10 44 11 36 12 28 13 20 14 12 15 4
16 62 17 54 18 46 19 38 20 30 21 22 22 14 23 6
24 64 25 56 26 48 27 40 28 32 29 24 30 16 31 8
32 57 33 49 34 41 35 33 36 25 37 17 38 9 39 1
40 59 41 51 42 43 43 35 44 27 45 19 46 11 47 3
48 61 49 53 50 45 51 37 52 29 53 21 54 13 55 5
56 63 57 55 58 47 59 39 60 31 61 23 62 15 63 7}
array set FP {
0 40 1 8 2 48 3 16 4 56 5 24 6 64 7 32
8 39 9 7 10 47 11 15 12 55 13 23 14 63 15 31
16 38 17 6 18 46 19 14 20 54 21 22 22 62 23 30
24 37 25 5 26 45 27 13 28 53 29 21 30 61 31 29
32 36 33 4 34 44 35 12 36 52 37 20 38 60 39 28
40 35 41 3 42 43 43 11 44 51 45 19 46 59 47 27
48 34 49 2 50 42 51 10 52 50 53 18 54 58 55 26
56 33 57 1 58 41 59 9 60 49 61 17 62 57 63 25}
array set PC1_C {
0 57 1 49 2 41 3 33 4 25 5 17 6 9
7 1 8 58 9 50 10 42 11 34 12 26 13 18
14 10 15 2 16 59 17 51 18 43 19 35 20 27
21 19 22 11 23 3 24 60 25 52 26 44 27 36}
array set PC1_D {
0 63 1 55 2 47 3 39 4 31 5 23 6 15
7 7 8 62 9 54 10 46 11 38 12 30 13 22
14 14 15 6 16 61 17 53 18 45 19 37 20 29
21 21 22 13 23 5 24 28 25 20 26 12 27 4}
array set shifts {
0 1 1 1 2 2 3 2 4 2 5 2 6 2 7 2
8 1 9 2 10 2 11 2 12 2 13 2 14 2 15 1}
array set PC2_C {
0 14 1 17 2 11 3 24 4 1 5 5
6 3 7 28 8 15 9 6 10 21 11 10
12 23 13 19 14 12 15 4 16 26 17 8
18 16 19 7 20 27 21 20 22 13 23 2}
array set PC2_D {
0 41 1 52 2 31 3 37 4 47 5 55
6 30 7 40 8 51 9 45 10 33 11 48
12 44 13 49 14 39 15 56 16 34 17 53
18 46 19 42 20 50 21 36 22 29 23 32}
array set e {
0 32 1 1 2 2 3 3 4 4 5 5
6 4 7 5 8 6 9 7 10 8 11 9
12 8 13 9 14 10 15 11 16 12 17 13
18 12 19 13 20 14 21 15 22 16 23 17
24 16 25 17 26 18 27 19 28 20 29 21
30 20 31 21 32 22 33 23 34 24 35 25
36 24 37 25 38 26 39 27 40 28 41 29
42 28 43 29 44 30 45 31 46 32 47 1}
array set S {
0,0 14 0,1 4 0,2 13 0,3 1 0,4 2 0,5 15 0,6 11 0,7 8
0,8 3 0,9 10 0,10 6 0,11 12 0,12 5 0,13 9 0,14 0 0,15 7
0,16 0 0,17 15 0,18 7 0,19 4 0,20 14 0,21 2 0,22 13 0,23 1
0,24 10 0,25 6 0,26 12 0,27 11 0,28 9 0,29 5 0,30 3 0,31 8
0,32 4 0,33 1 0,34 14 0,35 8 0,36 13 0,37 6 0,38 2 0,39 11
0,40 15 0,41 12 0,42 9 0,43 7 0,44 3 0,45 10 0,46 5 0,47 0
0,48 15 0,49 12 0,50 8 0,51 2 0,52 4 0,53 9 0,54 1 0,55 7
0,56 5 0,57 11 0,58 3 0,59 14 0,60 10 0,61 0 0,62 6 0,63 13
1,0 15 1,1 1 1,2 8 1,3 14 1,4 6 1,5 11 1,6 3 1,7 4
1,8 9 1,9 7 1,10 2 1,11 13 1,12 12 1,13 0 1,14 5 1,15 10
1,16 3 1,17 13 1,18 4 1,19 7 1,20 15 1,21 2 1,22 8 1,23 14
1,24 12 1,25 0 1,26 1 1,27 10 1,28 6 1,29 9 1,30 11 1,31 5
1,32 0 1,33 14 1,34 7 1,35 11 1,36 10 1,37 4 1,38 13 1,39 1
1,40 5 1,41 8 1,42 12 1,43 6 1,44 9 1,45 3 1,46 2 1,47 15
1,48 13 1,49 8 1,50 10 1,51 1 1,52 3 1,53 15 1,54 4 1,55 2
1,56 11 1,57 6 1,58 7 1,59 12 1,60 0 1,61 5 1,62 14 1,63 9
2,0 10 2,1 0 2,2 9 2,3 14 2,4 6 2,5 3 2,6 15 2,7 5
2,8 1 2,9 13 2,10 12 2,11 7 2,12 11 2,13 4 2,14 2 2,15 8
2,16 13 2,17 7 2,18 0 2,19 9 2,20 3 2,21 4 2,22 6 2,23 10
2,24 2 2,25 8 2,26 5 2,27 14 2,28 12 2,29 11 2,30 15 2,31 1
2,32 13 2,33 6 2,34 4 2,35 9 2,36 8 2,37 15 2,38 3 2,39 0
2,40 11 2,41 1 2,42 2 2,43 12 2,44 5 2,45 10 2,46 14 2,47 7
2,48 1 2,49 10 2,50 13 2,51 0 2,52 6 2,53 9 2,54 8 2,55 7
2,56 4 2,57 15 2,58 14 2,59 3 2,60 11 2,61 5 2,62 2 2,63 12
3,0 7 3,1 13 3,2 14 3,3 3 3,4 0 3,5 6 3,6 9 3,7 10
3,8 1 3,9 2 3,10 8 3,11 5 3,12 11 3,13 12 3,14 4 3,15 15
3,16 13 3,17 8 3,18 11 3,19 5 3,20 6 3,21 15 3,22 0 3,23 3
3,24 4 3,25 7 3,26 2 3,27 12 3,28 1 3,29 10 3,30 14 3,31 9
3,32 10 3,33 6 3,34 9 3,35 0 3,36 12 3,37 11 3,38 7 3,39 13
3,40 15 3,41 1 3,42 3 3,43 14 3,44 5 3,45 2 3,46 8 3,47 4
3,48 3 3,49 15 3,50 0 3,51 6 3,52 10 3,53 1 3,54 13 3,55 8
3,56 9 3,57 4 3,58 5 3,59 11 3,60 12 3,61 7 3,62 2 3,63 14
4,0 2 4,1 12 4,2 4 4,3 1 4,4 7 4,5 10 4,6 11 4,7 6
4,8 8 4,9 5 4,10 3 4,11 15 4,12 13 4,13 0 4,14 14 4,15 9
4,16 14 4,17 11 4,18 2 4,19 12 4,20 4 4,21 7 4,22 13 4,23 1
4,24 5 4,25 0 4,26 15 4,27 10 4,28 3 4,29 9 4,30 8 4,31 6
4,32 4 4,33 2 4,34 1 4,35 11 4,36 10 4,37 13 4,38 7 4,39 8
4,40 15 4,41 9 4,42 12 4,43 5 4,44 6 4,45 3 4,46 0 4,47 14
4,48 11 4,49 8 4,50 12 4,51 7 4,52 1 4,53 14 4,54 2 4,55 13
4,56 6 4,57 15 4,58 0 4,59 9 4,60 10 4,61 4 4,62 5 4,63 3
5,0 12 5,1 1 5,2 10 5,3 15 5,4 9 5,5 2 5,6 6 5,7 8
5,8 0 5,9 13 5,10 3 5,11 4 5,12 14 5,13 7 5,14 5 5,15 11
5,16 10 5,17 15 5,18 4 5,19 2 5,20 7 5,21 12 5,22 9 5,23 5
5,24 6 5,25 1 5,26 13 5,27 14 5,28 0 5,29 11 5,30 3 5,31 8
5,32 9 5,33 14 5,34 15 5,35 5 5,36 2 5,37 8 5,38 12 5,39 3
5,40 7 5,41 0 5,42 4 5,43 10 5,44 1 5,45 13 5,46 11 5,47 6
5,48 4 5,49 3 5,50 2 5,51 12 5,52 9 5,53 5 5,54 15 5,55 10
5,56 11 5,57 14 5,58 1 5,59 7 5,60 6 5,61 0 5,62 8 5,63 13
6,0 4 6,1 11 6,2 2 6,3 14 6,4 15 6,5 0 6,6 8 6,7 13
6,8 3 6,9 12 6,10 9 6,11 7 6,12 5 6,13 10 6,14 6 6,15 1
6,16 13 6,17 0 6,18 11 6,19 7 6,20 4 6,21 9 6,22 1 6,23 10
6,24 14 6,25 3 6,26 5 6,27 12 6,28 2 6,29 15 6,30 8 6,31 6
6,32 1 6,33 4 6,34 11 6,35 13 6,36 12 6,37 3 6,38 7 6,39 14
6,40 10 6,41 15 6,42 6 6,43 8 6,44 0 6,45 5 6,46 9 6,47 2
6,48 6 6,49 11 6,50 13 6,51 8 6,52 1 6,53 4 6,54 10 6,55 7
6,56 9 6,57 5 6,58 0 6,59 15 6,60 14 6,61 2 6,62 3 6,63 12
7,0 13 7,1 2 7,2 8 7,3 4 7,4 6 7,5 15 7,6 11 7,7 1
7,8 10 7,9 9 7,10 3 7,11 14 7,12 5 7,13 0 7,14 12 7,15 7
7,16 1 7,17 15 7,18 13 7,19 8 7,20 10 7,21 3 7,22 7 7,23 4
7,24 12 7,25 5 7,26 6 7,27 11 7,28 0 7,29 14 7,30 9 7,31 2
7,32 7 7,33 11 7,34 4 7,35 1 7,36 9 7,37 12 7,38 14 7,39 2
7,40 0 7,41 6 7,42 10 7,43 13 7,44 15 7,45 3 7,46 5 7,47 8
7,48 2 7,49 1 7,50 14 7,51 7 7,52 4 7,53 10 7,54 8 7,55 13
7,56 15 7,57 12 7,58 9 7,59 0 7,60 3 7,61 5 7,62 6 7,63 11}
array set P {
0 16 1 7 2 20 3 21
4 29 5 12 6 28 7 17
8 1 9 15 10 23 11 26
12 5 13 18 14 31 15 10
16 2 17 8 18 24 19 14
20 32 21 27 22 3 23 9
24 19 25 13 26 30 27 6
28 22 29 11 30 4 31 25}
for {set i 0} {$i < 66} {incr i} {
set block($i) 0
}
set pw [split $password ""]
set pw_pos 0
for {set i 0} {[scan [lindex $pw $pw_pos] %c c] !=3D -1 && =
$i < 64} \
{incr pw_pos} {
for {set j 0} {$j < 7} {incr j ; incr i} {
set block($i) [expr {($c >> (6 - $j)) & 01}]
}
incr i
}
for {set i 0} {$i < 28} {incr i} {
set C($i) $block([expr {$PC1_C($i) - 1}])
set D($i) $block([expr {$PC1_D($i) - 1}])
}
for {set i 0} {$i < 16} {incr i} {
for {set k 0} {$k < $shifts($i)} {incr k} {
set t $C(0)
for {set j 0} {$j < 27} {incr j} {
set C($j) $C([expr {$j + 1}])
}
set C(27) $t
set t $D(0)
for {set j 0} {$j < 27} {incr j} {
set D($j) $D([expr {$j + 1}])
}
set D(27) $t
}
for {set j 0} {$j < 24} {incr j} {
set KS($i,$j) $C([expr {$PC2_C($j) - 1}])
set KS($i,[expr {$j + 24}]) $D([expr {$PC2_D($j) - 28 - 1}])
}
}
for {set i 0} {$i < 48} {incr i} {
set E($i) $e($i)
}
for {set i 0} {$i < 66} {incr i} {
set block($i) 0
}
set salt [split $salt ""]
set salt_pos 0
set val_Z 90
set val_9 57
set val_period 46
for {set i 0} {$i < 2} {incr i} {
scan [lindex $salt $salt_pos] %c c
incr salt_pos
set iobuf($i) $c
if {$c > $val_Z} {
incr c -6
}
if {$c > $val_9} {
incr c -7
}
incr c -$val_period
for {set j 0} {$j < 6} {incr j} {
if {[expr {($c >> $j) & 01}]} {
set temp $E([expr {6 * $i + $j}])
set E([expr {6 * $i + $j}]) $E([expr {6 * $i + $j + =
24}])
set E([expr {6 * $i + $j + 24}]) $temp
}
}
}
set edflag 0
for {set h 0} {$h < 25} {incr h} {
for {set j 0} {$j < 64} {incr j} {
set L($j) $block([expr {$IP($j) - 1}])
}
for {set ii 0} {$ii < 16} {incr ii} {
if {$edflag} {
set i [expr {15 - $ii}]
} else {
set i $ii
}
for {set j 0} {$j < 32} {incr j} {
set tempL($j) $L([expr {$j + 32}])
}
for {set j 0} {$j < 48} {incr j} {
set preS($j) [expr {$L([expr {$E($j) - 1 + 32}]) ^ =
$KS($i,$j)}]
}
for {set j 0} {$j < 8} {incr j} {
set t [expr {6 * $j}]
set k $S($j,[expr {($preS($t) << 5) + =
\
($preS([expr {$t + 1}]) << 3) + =
\
($preS([expr {$t + 2}]) << 2) + =
\
($preS([expr {$t + 3}]) << 1) + =
\
$preS([expr {$t + 4}]) + \
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -