shl加密
/* 收藏的一个MD5加密解密
1、 MD5String、MD5File、MD5Print、MD5Match这四个函数是供调用的。其他是用来辅助这几个函///////数//的子函数。
2、MD5String为加密字符串。
3、MD5File为加密这个文件。
4、MD5Print是将加密后的密文转换成字符串。
5、MD5Match是用来比较密文是否一致。
加密字符串aaa MD5String('aaa')
将加密后的aaa显示出来 MD5Print(MD5String('aaa'))
比较两次密文是否一致: MD5Match(MD5String('第一次明文'),MD5String('第二次输入的明文'))
*/
unit U_MD5;
// -----------------------------------------------------------------------------------------------
INTERFACE
// -----------------------------------------------------------------------------------------------
uses
Windows;
type
MD5Count = array[0..1] of DWORD;
MD5State = array[0..3] of DWORD;
MD5Block = array[0..15] of DWORD;
MD5CBits = array[0..7] of byte;
MD5Digest = array[0..15] of byte;
MD5Buffer = array[0..63] of byte;
MD5Context = record
State: MD5State;
Count: MD5Count;
Buffer: MD5Buffer;
end;
procere MD5Init(var Context: MD5Context);
procere MD5Update(var Context: MD5Context; Input: pChar; Length: longword);
procere MD5Final(var Context: MD5Context; var Digest: MD5Digest);
function MD5String(M: string): MD5Digest;
function MD5File(N: string): MD5Digest;
function MD5Print(D: MD5Digest): string;
function MD5Match(D1, D2: MD5Digest): boolean;
// -----------------------------------------------------------------------------------------------
IMPLEMENTATION
// -----------------------------------------------------------------------------------------------
var
PADDING: MD5Buffer = (
$80, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00
);
function F(x, y, z: DWORD): DWORD;
begin
Result := (x and y) or ((not x) and z);
end;
function G(x, y, z: DWORD): DWORD;
begin
Result := (x and z) or (y and (not z));
end;
function H(x, y, z: DWORD): DWORD;
begin
Result := x xor y xor z;
end;
function I(x, y, z: DWORD): DWORD;
begin
Result := y xor (x or (not z));
end;
procere rot(var x: DWORD; n: BYTE);
begin
x := (x shl n) or (x shr (32 - n));
end;
procere FF(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
inc(a, F(b, c, d) + x + ac);
rot(a, s);
inc(a, b);
end;
procere GG(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
inc(a, G(b, c, d) + x + ac);
rot(a, s);
inc(a, b);
end;
procere HH(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
inc(a, H(b, c, d) + x + ac);
rot(a, s);
inc(a, b);
end;
procere II(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
inc(a, I(b, c, d) + x + ac);
rot(a, s);
inc(a, b);
end;
// -----------------------------------------------------------------------------------------------
// Encode Count bytes at Source into (Count / 4) DWORDs at Target
procere Encode(Source, Target: pointer; Count: longword);
var
S: PByte;
T: PDWORD;
I: longword;
begin
S := Source;
T := Target;
for I := 1 to Count div 4 do begin
T^ := S^;
inc(S);
T^ := T^ or (S^ shl 8);
inc(S);
T^ := T^ or (S^ shl 16);
inc(S);
T^ := T^ or (S^ shl 24);
inc(S);
inc(T);
end;
end;
// Decode Count DWORDs at Source into (Count * 4) Bytes at Target
procere Decode(Source, Target: pointer; Count: longword);
var
S: PDWORD;
T: PByte;
I: longword;
begin
S := Source;
T := Target;
for I := 1 to Count do begin
T^ := S^ and $ff;
inc(T);
T^ := (S^ shr 8) and $ff;
inc(T);
T^ := (S^ shr 16) and $ff;
inc(T);
T^ := (S^ shr 24) and $ff;
inc(T);
inc(S);
end;
end;
// Transform State according to first 64 bytes at Buffer
procere Transform(Buffer: pointer; var State: MD5State);
var
a, b, c, d: DWORD;
Block: MD5Block;
begin
Encode(Buffer, @Block, 64);
a := State[0];
b := State[1];
c := State[2];
d := State[3];
FF (a, b, c, d, Block[ 0], 7, $d76aa478);
FF (d, a, b, c, Block[ 1], 12, $e8c7b756);
FF (c, d, a, b, Block[ 2], 17, $242070db);
FF (b, c, d, a, Block[ 3], 22, $c1bdceee);
FF (a, b, c, d, Block[ 4], 7, $f57c0faf);
FF (d, a, b, c, Block[ 5], 12, $4787c62a);
FF (c, d, a, b, Block[ 6], 17, $a8304613);
FF (b, c, d, a, Block[ 7], 22, $fd469501);
FF (a, b, c, d, Block[ 8], 7, $698098d8);
FF (d, a, b, c, Block[ 9], 12, $8b44f7af);
FF (c, d, a, b, Block[10], 17, $ffff5bb1);
FF (b, c, d, a, Block[11], 22, $895cd7be);
FF (a, b, c, d, Block[12], 7, $6b901122);
FF (d, a, b, c, Block[13], 12, $fd987193);
FF (c, d, a, b, Block[14], 17, $a679438e);
FF (b, c, d, a, Block[15], 22, $49b40821);
GG (a, b, c, d, Block[ 1], 5, $f61e2562);
GG (d, a, b, c, Block[ 6], 9, $c040b340);
GG (c, d, a, b, Block[11], 14, $265e5a51);
GG (b, c, d, a, Block[ 0], 20, $e9b6c7aa);
GG (a, b, c, d, Block[ 5], 5, $d62f105d);
GG (d, a, b, c, Block[10], 9, $2441453);
GG (c, d, a, b, Block[15], 14, $d8a1e681);
GG (b, c, d, a, Block[ 4], 20, $e7d3fbc8);
GG (a, b, c, d, Block[ 9], 5, $21e1cde6);
GG (d, a, b, c, Block[14], 9, $c33707d6);
GG (c, d, a, b, Block[ 3], 14, $f4d50d87);
GG (b, c, d, a, Block[ 8], 20, $455a14ed);
GG (a, b, c, d, Block[13], 5, $a9e3e905);
GG (d, a, b, c, Block[ 2], 9, $fcefa3f8);
GG (c, d, a, b, Block[ 7], 14, $676f02d9);
GG (b, c, d, a, Block[12], 20, $8d2a4c8a);
HH (a, b, c, d, Block[ 5], 4, $fffa3942);
HH (d, a, b, c, Block[ 8], 11, $8771f681);
HH (c, d, a, b, Block[11], 16, $6d9d6122);
HH (b, c, d, a, Block[14], 23, $fde5380c);
HH (a, b, c, d, Block[ 1], 4, $a4beea44);
HH (d, a, b, c, Block[ 4], 11, $4bdecfa9);
HH (c, d, a, b, Block[ 7], 16, $f6bb4b60);
HH (b, c, d, a, Block[10], 23, $bebfbc70);
HH (a, b, c, d, Block[13], 4, $289b7ec6);
HH (d, a, b, c, Block[ 0], 11, $eaa127fa);
HH (c, d, a, b, Block[ 3], 16, $d4ef3085);
HH (b, c, d, a, Block[ 6], 23, $4881d05);
HH (a, b, c, d, Block[ 9], 4, $d9d4d039);
HH (d, a, b, c, Block[12], 11, $e6db99e5);
HH (c, d, a, b, Block[15], 16, $1fa27cf8);
HH (b, c, d, a, Block[ 2], 23, $c4ac5665);
II (a, b, c, d, Block[ 0], 6, $f4292244);
II (d, a, b, c, Block[ 7], 10, $432aff97);
II (c, d, a, b, Block[14], 15, $ab9423a7);
II (b, c, d, a, Block[ 5], 21, $fc93a039);
II (a, b, c, d, Block[12], 6, $655b59c3);
II (d, a, b, c, Block[ 3], 10, $8f0ccc92);
II (c, d, a, b, Block[10], 15, $ffeff47d);
II (b, c, d, a, Block[ 1], 21, $85845dd1);
II (a, b, c, d, Block[ 8], 6, $6fa87e4f);
II (d, a, b, c, Block[15], 10, $fe2ce6e0);
II (c, d, a, b, Block[ 6], 15, $a3014314);
II (b, c, d, a, Block[13], 21, $4e0811a1);
II (a, b, c, d, Block[ 4], 6, $f7537e82);
II (d, a, b, c, Block[11], 10, $bd3af235);
II (c, d, a, b, Block[ 2], 15, $2ad7d2bb);
II (b, c, d, a, Block[ 9], 21, $eb86d391);
inc(State[0], a);
inc(State[1], b);
inc(State[2], c);
inc(State[3], d);
end;
// -----------------------------------------------------------------------------------------------
// Initialize given Context
procere MD5Init(var Context: MD5Context);
begin
with Context do begin
State[0] := $67452301;
State[1] := $efcdab89;
State[2] := $98badcfe;
State[3] := $10325476;
Count[0] := 0;
Count[1] := 0;
ZeroMemory(@Buffer, SizeOf(MD5Buffer));
end;
end;
// Update given Context to include Length bytes of Input
procere MD5Update(var Context: MD5Context; Input: pChar; Length: longword);
var
Index: longword;
PartLen: longword;
I: longword;
begin
with Context do begin
Index := (Count[0] shr 3) and $3f;
inc(Count[0], Length shl 3);
if Count[0] < (Length shl 3) then inc(Count[1]);
inc(Count[1], Length shr 29);
end;
PartLen := 64 - Index;
if Length >= PartLen then begin
CopyMemory(@Context.Buffer[Index], Input, PartLen);
Transform(@Context.Buffer, Context.State);
I := PartLen;
while I + 63 < Length do begin
Transform(@Input[I], Context.State);
inc(I, 64);
end;
Index := 0;
end else I := 0;
CopyMemory(@Context.Buffer[Index], @Input[I], Length - I);
end;
// Finalize given Context, create Digest and zeroize Context
procere MD5Final(var Context: MD5Context; var Digest: MD5Digest);
var
Bits: MD5CBits;
Index: longword;
PadLen: longword;
begin
Decode(@Context.Count, @Bits, 2);
Index := (Context.Count[0] shr 3) and $3f;
if Index < 56 then PadLen := 56 - Index else PadLen := 120 - Index;
MD5Update(Context, @PADDING, PadLen);
MD5Update(Context, @Bits, 8);
Decode(@Context.State, @Digest, 4);
ZeroMemory(@Context, SizeOf(MD5Context));
end;
// -----------------------------------------------------------------------------------------------
// Create digest of given Message
function MD5String(M: string): MD5Digest;
var
Context: MD5Context;
begin
MD5Init(Context);
MD5Update(Context, pChar(M), length(M));
MD5Final(Context, Result);
end;
// Create digest of file with given Name
function MD5File(N: string): MD5Digest;
var
FileHandle: THandle;
MapHandle: THandle;
ViewPointer: pointer;
Context: MD5Context;
begin
MD5Init(Context);
FileHandle := CreateFile(pChar(N), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FileHandle <> INVALID_HANDLE_VALUE then try
MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if MapHandle <> 0 then try
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
if ViewPointer <> nil then try
MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil));
finally
UnmapViewOfFile(ViewPointer);
end;
finally
CloseHandle(MapHandle);
end;
finally
CloseHandle(FileHandle);
end;
MD5Final(Context, Result);
end;
// Create hex representation of given Digest
function MD5Print(D: MD5Digest): string;
var
I: byte;
const
Digits: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
begin
Result := '';
for I := 0 to 15 do Result := Result + Digits[(D[I] shr 4) and $0f] + Digits[D[I] and $0f];
end;
// -----------------------------------------------------------------------------------------------
// Compare two Digests
function MD5Match(D1, D2: MD5Digest): boolean;
var
I: byte;
begin
I := 0;
Result := TRUE;
while Result and (I < 16) do begin
Result := D1[I] = D2[I];
inc(I);
end;
end;
end.
Ⅱ 如何使用外壳工具完成加密
如何使用外 具完成加密 使用外 密工具,开发商可以在没有程序源 或不对程序源 做任何改动的情况下快捷地完成 加密工作,并保证有着较高的加密强度。若没有相应的硬件狗存在,加密后的程序将无法启动。 外 密工具的特点 1、 使用三种方式加密:外壳、嵌入、内外结合。 外 所谓外壳,是加密工具加到被加密程序的一部分程序。加密程序启动时外 先被执行。外壳 要检查硬件狗的存在性和一致性。如果对应的硬件狗存在,则进入原程序的入 否则终止程序。外壳只 在加密程序启动时执行一次。 嵌入 所谓嵌入,是加密工具在被加密程序中嵌入一个公共程序,加密程序在整个运行期内以一定的 频率执行这个公共程序,该程序检查硬件狗的存在性和一致性。如果对应的硬件狗存在,则继续执行原程 序,否则终止程序。本加密方式可选。 内外结合 如果被加密的程序已经调用了赛孚耐公司提供的接口函数,那么外壳程序会通知接口函数, 外 序是否已经被执行,以防止外壳程序被跳过。如果发现外壳程序没有被执行,会终止程序。 这些数据文件由您的应用程序使用, 或者由受保护的应用程序产生 (输 2、 可以对数据文件进行加密, 出文件) 。这些文件只能由受保护的应用程序读取。 3、 可以通过关联许可证文件灵活地限制使用时间。 4、 可以自定义查硬件狗错误时显示给用户的提示信息,也可以选择不显示提示信息。 5、 外 护是一个多层的体系结构。只有前一层执行成功,才会 紧相连的一层。这种多层体系 结构可为您的应用程序提供额外的保护--这与用多道锁为您的门提供保护的功能相似。突破这 些保护层需要更多资源、时间和技巧,可以有效的阻止黑客攻击。此外,由于采用了多层随机模 式,所以任何两次被外 密的应用程序均不相同。 外 密工具可以加密 32/64 位 Windows 程序,在宏狗安装目录下\10003(您的软件系列号) \Shell\Win32shl.exe。 应用示例 下面以使用一个硬件狗保护 Notepad.exe 和 Calc.exe 为例说明外 密工具的使用。 在使用之前假设已 经使用开发商工具在文件系统中创建了两个许可证文件(许可证文件的文件夹 ID 为 16128 ,文件 ID 分 别为 10 和 20) 。关于如何创建许可证文件请查阅开发商手册开发商工具的使用一章。 1.请先插入硬件狗,执行步骤 1,如图 1 所示,指定要加密的 EXE 文件。 第 1 页 步骤 1: 单击浏览按钮, 指定要加密的 EXE 文 件;或在“源文件”文 本框中输入 要加密的 EXE 文件的路径和文 件名。 图 1 指定源文件后,系统会在“目标路径”文本框中自动添加加密后的 EXE 文件(即目标文件)存放的路 径。系统默认将目标文件存放到 OUTPUT 路径下,我们建议用户采用这种默认方式。 如果目标文件存在,覆盖它 如果选中“如果目标文件已存在,覆盖它”复选框,当目标文件所在路径下有同名文件存在,加密过 程不再出现是否覆盖文件的提示信息。 2.对加密狗的硬件参数进行设置。 产品名称 加密后的应用程序在运行时会查找与系列号和产品名称相一致的硬件狗。可以此处指定产品名称。 查找方式 通过选择查找方式,能够更快地、更准 找到硬件狗。请选择适合您的应用程序的查找方式。 用户 加密后的应用程序在运行时会访问硬件狗,请指定硬件狗的用户 。 嵌入 第 2 页 加密软件运行期间,可以不断地检查对应的硬件狗是否存在。如果清空“嵌入”复选框,则在程序运 行期间不检查硬件狗。如果选中“嵌入”复选框,当程序运行期间检查不到对应的硬件狗时,程序会停止 运行。您可以指定检查间隔,间隔以秒为单位。缺省值为 120 秒,即 2 分钟。 .NET 增强 .NET 增强功能为纯.NET 应用程序(EXE 和 DLL)提供了增强的安全性。此功能可执行以下操作: 隐藏原始入口点方法(仅用于.NET 可执行文件) 加密原始应用程序的字符串 加密原始应用程序的常量 (用于 32 位.NET 应用程序) SDNPro64.dll 和 (用于 64 位.NET 如果选择了此功能, 则需要将 SDNPro.dll 应用程序)与受保护应用程序一起提供给最终用户。 注意 使用.NET 增强特征项(使用.Net 增强保护外 NET 应用程序)的前提条件是机器中应安装了同 一版本的.NETFramework 和.NET SDK。.NET 增强选项不支持混合代码应用程序。 多层保护级别 外 提供多层保护。因为应用程序和外 之间的连接处非常容易受到攻击,所以您可以选择使用 多层外 从第 1 级到第 5 级)来保护您的应用程序。第 1 级可提供合理的保护,而第 5 级可提供最强保 护。但是,随着每一保护级别的增加,应用程序的大小和用于启动的时间也会相应增加。在缺省情况下, 使用第 3 级保护方式。 隐藏导入符号 选定此复选框隐藏您的程序中的导入符号。但是,请注意该选项不适用于此处所列出的文件类型使SmartHeap DLLs 的应用程序 当您同时加密数据文件或者使用数据文件加密选项时 如果存在要实施保护的任意数据文件或已指定了文件加密设置,则将忽略隐藏导入符号选项。 我使用了外 SDK 如果您已经使用外壳软件开发工具包(位于\Shell SDK 文件夹下)来保护您的重要 段、常量和字 符串数据,则选中此复选框。参阅该文件夹中的自述文件获得详细信息。 存在调试器时允许我的应用程序运行 您可以不选择该复选框,禁止在出现调试器时执行应用程序。如果在系统中探测到调试器,被保护的 应用程序将退出。非恶意用户可以关闭调试器,重新启动应用程序。但是,如果出于某种原因,您需要在 存在调试器的情况下允许您的应用程序运行,则选择该复选框。 3.执行步骤 2、3、4、5、6,如图 2、3 所示,关联许可证文件。 步骤 2: 单 击“关联 许可证文 件”按钮。 图 2 第 4 页 步骤 3:选择 “关联许可 证文件” 。 步骤 4: 指定文件 夹 ID。 步骤 5: 指定文件 ID。 步骤 6:单击 “ ”按钮。 图 3 注意 许可证文件将被关联到主界面上的源文件。如果主界面上的源文件是一个动态连接库文件,在 此动态连接库被加载到内存中时,会调用 RC_VisitLicenseFile 函数检查许可证文件。关于 RC_VisitLicenseFile 函数的说明,请查阅开发商手册 API 接口函数说明部分。 4.我们提供了 19 种不同错误类型的错误信息,请根据具体情况分别指定其内容。标题限制在 60 字节 内,每条消息限制在 100 字节内。执行步骤 7、8、9、10、11、12,如图 4、5 所示,设置提示消息。 第 5 页 步骤 7:单 击“设置提 示消息”出 , 现如下图的 界面。 图 4 第 6 页 步骤 8: 在查硬件 狗出现错误时, 如需要显示提示 信息,则选中此 复选框;否则清 空此复选框。 步骤 10: 根据 需要, 修改提 示信息对话 框的内容。 步骤 9:根 据需要,修 改提示信息 对话框的标 题。 步骤 12:单击 “ ”按钮。 图 5 步骤 11:根据需 要,选择错误消 息的类型:窗口 消息或者控制台 消息。 5.如果在加密 EXE 文件的同时需要加密数据文件,执行步骤 13,如图 6 所示: 第 7 页 步骤 13: 单击 “设置要加 密的数据文 件”按钮。 图 6 6.指定要加密的数据文件(实际上 Notepad.exe 执行时不需要数据库文件,这里只是一个加密演示) , 执行步骤 14,如图 7 所示: 步骤 14:单 击 浏 览 按 钮,指定要 加密的数据 文件。 图 7 7.执行步骤 15,如图 8 所示,将数据文件加入文件列表。如需加入多个数据文件,请重复步骤 14 和 15。此时文件加密选项会根据文件列表进行自动设置,如果您要进一步对其进行设置,例如,当您要加 第 8 页 密新生成的数据文件(输出文件)时,执行步骤 16 更改文件加密选项。注意:在执行步骤 16 前,请插上 狗。外壳工具会从狗里获得狗的 ID 作为默认的加密种子。 步骤 15: “增 单击 加到文件列表” 按 钮, 将要加密的数 据文件加入文件 列表。 步骤 16: 单击 此处文本。 图 8 8.在文本编辑框中已经包含“*.DBF;” ,例如,为了加密受保护的程序在运行过程中生成的文本文件, 执行步骤 17,在文本编辑框中添加“*.TXT;” 。如果想要指定自己的加密种子,执行步骤 18,选中“指定 我自己的加密种子”复选框,并在文本编辑框中输入自定义的加密种子。另外,为了提高安全性,2.0 版本 的外壳工具默认会使用 AES 算法对数据文件进行加密,而以前的版本用的是私有算法。如果要保持跟以前 版本的兼容性而使用私有算法,可以不选中“使用 AES 算法加密”复选框。执行步骤 20,返回“设置要 加密的数据文件”对话框,单击 按钮完成数据文件加密设置。 步骤 18:指定自己 的加密种子。 步骤 17:修改或添 加文件过滤器。 步骤 19:指定是否 使用 AES 算法加密 步骤 20:点击 定按钮。 图 9 9.完成有关 Notepad.exe 的所有设置后执行步骤 21,如图 10 所示,将其加入加密中心,成为加密队 列中的一个加密项。然后对 Calc.exe 重复步骤 1-21,如果需要关联许可证文件,请修改“文件 ID” 的值,如图 11 所示。使 Calc.exe 和 Notepad.exe 运行时访问不同的许可证文件。 第 9 页 步骤 21: 单击 “加入加密 队列” 单击此按钮,可 将选中的加密项 清除。 单击此按钮可 查看某个加密 项的所有设置 信息。 单击此按 钮,可清 除所有加 密项。 图 10 将文件 ID 设 置为:20。 图 11 9.可以将加密中心所有加密项的设置存成一个配置文件,以供下一次使用。执行步骤 22-24,如图 12 所示。 第 10 页 步骤 22: 单 击此按钮。 步骤 23: 单击“存 储配置文 件” 命令。 步骤 24:键入 配置文件名后, 单击 “保存”按 钮。 图 12 10.执行步骤 25,如图 13 所示,执行加密操作。 步骤 25: 单击“加 密” 按钮。 图 13 11.加密过程中会出现如下图所示的对话框。 第 11 页 在加密过程中,单 击“中止”按钮可 中止加密操作。 图 14 进程条指示加密正在进行。加密结束后会提示结果。如果加密成功,过 2 秒后,程序自动加密下 一个文件。如果加密失败,会提示失败原因,并给出解决措施或错误码,关于错误码的定义请下面的 保护时的错误 。错误信息会左右移动,以引起您的注意。至此,完成了对 Notepad.exe 和 Calc.exe 的保护。 保护时的错误 下表列出了保护应用程序和数据文件时可能产生的错误,对不不在下表中的错误代码,请参见安 装目录下的 errcode-chn.txt。 错误码 (十六进制) 194 SP_ERR_NOT_ENOUGH_MEMORY 没有足够的资源来保护应用程序。
Ⅲ 我想问下python中 逻辑与:“&”和“and”的区别
1、“&”和“and”有本质区别,属于不同类型的运行符号。& 是位运算;and 是逻辑运算。
2、首先是&:该运输符属于字符串的连接运算符,例如,“w“&”c“结果为字符串”wc“。
3、and属于逻辑运算符,表示逻辑与运算,其规则是有假取假,全真为真。例如,true and false结果为false,true and true结果为true。
(3)shl加密扩展阅读
Python的设计哲学是“优雅”、“明确”、“简单”。因此,Perl语言中“总是有多种方法来做同一件事”的理念在Python开发者中通常是难以忍受的。Python开发者的哲学是“用一种方法,最好是只有一种方法来做一件事”。
在设计Python语言时,如果面临多种选择,Python开发者一般会拒绝花俏的语法,而选择明确的没有或者很少有歧义的语法。
由于这种设计观念的差异,Python源代码通常被认为比Perl具备更好的可读性,并且能够支撑大规模的软件开发。这些准则被称为Python格言。在Python解释器内运行import this可以获得完整的列表。
Python开发人员尽量避开不成熟或者不重要的优化。一些针对非重要部位的加快运行速度的补丁通常不会被合并到Python内。所以很多人认为Python很慢。
不过,根据二八定律,大多数程序对速度要求不高。在某些对运行速度要求很高的情况,Python设计师倾向于使用JIT技术,或者用使用C/C++语言改写这部分程序。可用的JIT技术是PyPy。
Python是完全面向对象的语言。函数、模块、数字、字符串都是对象。并且完全支持继承、重载、派生、多继承,有益于增强源代码的复用性。
Python支持重载运算符和动态类型。相对于Lisp这种传统的函数式编程语言,Python对函数式设计只提供了有限的支持。有两个标准库(functools, itertools)提供了Haskell和Standard ML中久经考验的函数式程序设计工具。
虽然Python可能被粗略地分类为“脚本语言”(script language),但实际上一些大规模软件开发计划例如Zope、Mnet及BitTorrent,Google也广泛地使用它。
Python的支持者较喜欢称它为一种高级动态编程语言,原因是“脚本语言”泛指仅作简单程序设计任务的语言,如shellscript、VBScript等只能处理简单任务的编程语言,并不能与Python相提并论。
Python本身被设计为可扩充的。并非所有的特性和功能都集成到语言核心。Python提供了丰富的API和工具,以便程序员能够轻松地使用C语言、C++、Cython来编写扩充模块。Python编译器本身也可以被集成到其它需要脚本语言的程序内。
因此,很多人还把Python作为一种“胶水语言”(glue language)使用。使用Python将其他语言编写的程序进行集成和封装。在Google内部的很多项目,例如Google Engine使用C++编写性能要求极高的部分,然后用Python或Java/Go调用相应的模块。
《Python技术手册》的作者马特利(Alex Martelli)说:“这很难讲,不过,2004 年,Python 已在Google内部使用,Google 召募许多 Python 高手,但在这之前就已决定使用Python,
他们的目的是 Python where we can, C++ where we must,在操控硬件的场合使用 C++,在快速开发时候使用 Python。”