65.9K
CodeProject 正在变化。 阅读更多。
Home

PL/I 教程 – 基本加密示例

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2012 年 11 月 26 日

CPOL

4分钟阅读

viewsIcon

56723

downloadIcon

265

基于加密示例的 PL/I 基本概念教程

范围  

本文的目的是提供 PL/I 编程的示例,以帮助那些不得不
使用这种语言的人(没有人会自愿选择使用 PL1 在家里构建东西……)从第一天起就富有成效。 该示例是一个“加密”和“解密”用户输入的文本的程序。 

我将带领读者了解该程序,以便他们理解这种语言的所有基本概念和命令。 

关于 PL/I 语言

编程语言 PL/I 或 PL/1(读作“P L ONE”)是 IBM 的专有语言。 由于它是封闭的,并且在野外无法获得编译器(除了 IBM 的编译器之外),该语言并没有流行起来。 现在它被用于世界各地各大银行的 zOS 大型机核心银行系统中。 

PL/I 编译器 

搜索 http://www.tek-tips.com/viewthread.cfm?qid=1669923 以查找 Windows 的 PL/I 编译器。 该编译器位于 ftp://ftp.software.ibm.com/ps/products/pli/demos/ 并且可以在 Windows XP 中执行。 因此,如果您有 Windows 7 或 8 或更新的版本,您必须下载 Windows XP 虚拟机(参见 Windows Virtual PC)才能执行它并用 PL/I 编写程序。  

下载并安装到 XP 机器后,请按如下方式使用它

  • 输入 'pli nameoftheprogram.pli' 以进行编译 
  • 输入 'ilink nameoftheprogram.obj' 以链接到可执行文件  

程序

该程序具有以下组件。 

1. 主程序:在此过程中,程序要求用户选择程序的模式(加密/解密)。 然后,它要求用户输入要加密或解密的文本,并调用相关的内部程序(函数)来执行所选的操作。 操作的输出呈现给用户,并且程序终止。

声明变量

	/* PROCEDURE ENCRYPTOR  */
 
	SKAKOS1: PROC OPTIONS(MAIN) REORDER;
      
	DCL ENCRYPT_KEY DEC(2) INIT (1);
	DCL DECRYPT_KEY DEC(2) INIT (1);
	DCL USER_TEXT CHAR(50) INIT (' ');
	DCL RESULT CHAR(100) INIT (' ');
	DCL HUO0 CHAR(1) INIT (' ');
	DCL HUO1 CHAR(1) INIT (' ');
	DCL EXECMODE FIXED DEC (1);
	DCL STOPPROG FIXED DEC (1);
	DCL I FIXED DEC (2);
   
	ENCRYPT_KEY = 1;
	DECRYPT_KEY = 1; 

程序主程序  

	DO I = 1 TO 25;
	PUT SKIP LIST('');
	END;

        PUT SKIP LIST ('HUO ENCRYPTOR - CIA Version (128 bit)');
	PUT SKIP LIST(' ');
	PUT SKIP LIST('SELECT PROGRAM MODE (1 or 2)');
	PUT SKIP LIST('----------------------------');
	PUT SKIP LIST('OPTION 1: ENCRYPT');
	PUT SKIP LIST('OPTION 2: DECRYPT');
	PUT SKIP LIST(' ');
	GET SKIP(0) LIST(EXECMODE);
	PUT SKIP LIST(' ');

	PUT SKIP LIST('ENTER TEXT:');
	GET EDIT (USER_TEXT)(A(50));

	IF (EXECMODE = 1) THEN
	DO;
		RESULT = ENCRYPT(USER_TEXT);
	END;
	ELSE IF (EXECMODE = 2) THEN
	DO;
		RESULT = DECRYPT(USER_TEXT);
	END;
	
	PUT SKIP LIST(' ');
	PUT SKIP LIST ('RESULT: ' || RESULT);

	PUT SKIP LIST ('--- PROGRAM TERMINATED ---'); 

 

2. 加密程序:这是负责数据加密的函数。 它将要加密的文本作为输入,并返回加密的文本作为输出。 

加密过程如下:  

  • 按字母顺序读取输入字符串
  • 它调用 CHAR_TO_ASCII 函数以获取所读取字母的 ASCII 数值。 CHAR_TO_ASCII 函数将在稍后描述。
  • 它将 ASCII 值增加加密密钥值
  • 它通过 ASCII_TO_CHAR 函数再次将更改后的 ASCII 值转换为字符。 CHAR_TO_ASCII 函数将在稍后描述。
  • 它将读取的字母放入输出字符串中(直到处理完输入的所有字母)。 
	/*-------------------------------------------------------*/
	ENCRYPT:PROC(INPUT_TEXT) RETURNS(CHAR(50));

		DCL INPUT_TEXT CHAR(50);
		DCL OUTPUT_TEXT CHAR(50);
		DCL I DEC(2);
		DCL HUO0 CHAR(1);
		DCL HUO1 CHAR(1);

		OUTPUT_TEXT = INPUT_TEXT;
		/*PUT SKIP LIST('INPUT LENGTH: ',LENGTH(INPUT_TEXT));*/

		DO I = 1 TO LENGTH(INPUT_TEXT);
		   HUO0 = SUBSTR(INPUT_TEXT,I,1);

                   IF HUO0 = ' ' THEN DO;
		      HUO1 = ' ';
		   END;
		   ELSE DO;
		      HUO1 = ASCII_TO_CHAR((CHAR_TO_ASCII(HUO0) + ENCRYPT_KEY));
		   END;
		
		   SUBSTR(OUTPUT_TEXT,I,1) = HUO1;
		   /*PUT SKIP LIST('I = ' || I);*/
		END;

		RETURN(OUTPUT_TEXT);

	END ENCRYPT;
	/*-------------------------------------------------------*/ 

3. 解密程序:这是负责解密的函数。 它的逻辑与加密程序相同,但是它会减小字母的 ASCII 值(以便执行与加密函数相反的操作)。  

	/*-------------------------------------------------------*/
	DECRYPT:PROC(INPUT_TEXT) RETURNS(CHAR(50));

		DCL INPUT_TEXT CHAR(50);
		DCL OUTPUT_TEXT CHAR(50);
		DCL I DEC(2);
		DCL HUO0 CHAR(1);
		DCL HUO1 CHAR(1);

		OUTPUT_TEXT = INPUT_TEXT;

		DO I = 1 TO LENGTH(INPUT_TEXT);
		   HUO0 = SUBSTR(INPUT_TEXT,I,1);

                   IF HUO0 = ' ' THEN DO;
		      HUO1 = ' ';
		   END;
		   ELSE DO;
		      HUO1 = ASCII_TO_CHAR((CHAR_TO_ASCII(HUO0) - DECRYPT_KEY));
		   END;

		   SUBSTR(OUTPUT_TEXT,I,1) = HUO1;
		END ;

		RETURN(OUTPUT_TEXT);

	END DECRYPT;
	/*-------------------------------------------------------*/ 

4. CHAR_TO_ASCII 程序:此函数将一个字母(字符)作为输入,并返回对应于该特定字母的 ASCII 数值。 请注意,ASCII 值是“自制的”(由我定义,不遵循官方的 ASCII 编码)。

	/*-------------------------------------------------------*/
	CHAR_TO_ASCII:PROC(INPUT_CHAR) RETURNS(DEC(2));

		DCL INPUT_CHAR CHAR(1);
		DCL OUTPUT_NUM DEC(2);
		DCL DEBUG_NUM DEC(1);

		SELECT (INPUT_CHAR);
		   WHEN ('A') OUTPUT_NUM = 1;
		   WHEN ('B') OUTPUT_NUM = 2;
		   WHEN ('C') OUTPUT_NUM = 3;
		   WHEN ('D') OUTPUT_NUM = 4;
		   WHEN ('E') OUTPUT_NUM = 5;
		   WHEN ('F') OUTPUT_NUM = 6;
		   WHEN ('G') OUTPUT_NUM = 7;
		   WHEN ('H') OUTPUT_NUM = 8;
		   WHEN ('I') OUTPUT_NUM = 9;
		   WHEN ('J') OUTPUT_NUM = 10;
		   WHEN ('K') OUTPUT_NUM = 11;
		   WHEN ('L') OUTPUT_NUM = 12;
		   WHEN ('M') OUTPUT_NUM = 13;
		   WHEN ('N') OUTPUT_NUM = 14;
		   WHEN ('O') OUTPUT_NUM = 15;
		   WHEN ('P') OUTPUT_NUM = 16;
		   WHEN ('Q') OUTPUT_NUM = 17;
		   WHEN ('R') OUTPUT_NUM = 18;
		   WHEN ('S') OUTPUT_NUM = 19;
		   WHEN ('T') OUTPUT_NUM = 20;
		   WHEN ('U') OUTPUT_NUM = 21;
		   WHEN ('V') OUTPUT_NUM = 22;
		   WHEN ('W') OUTPUT_NUM = 23;
		   WHEN ('X') OUTPUT_NUM = 24;
		   WHEN ('Y') OUTPUT_NUM = 25;
		   WHEN ('Z') OUTPUT_NUM = 26;
		   OTHERWISE OUTPUT_NUM = 99;
		END;

		/*PUT SKIP LIST('DEBUG CHECKPOINT 4');*/

		RETURN(OUTPUT_NUM);

        END CHAR_TO_ASCII;
	/*-------------------------------------------------------*/ 

5. ASCII_TO_CHAR 程序:此内部程序执行与 CHAR_TO_ASCII 程序相反的功能。 它返回代表特定 ASCII 值的字符。

	/*-------------------------------------------------------*/
	ASCII_TO_CHAR:PROC(INPUT_ASCII) RETURNS(CHAR(1));

		DCL INPUT_ASCII DEC(2);
		DCL OUTPUT_CHAR CHAR(1);

		IF INPUT_ASCII = 27 THEN DO;
		INPUT_ASCII = 1;
		END;

		IF INPUT_ASCII < 0 THEN DO;
		INPUT_ASCII = 26;
		END;

		SELECT (INPUT_ASCII);
		   WHEN (99) OUTPUT_CHAR = ' ';
		   WHEN (1) OUTPUT_CHAR = 'A';
		   WHEN (2) OUTPUT_CHAR = 'B';
		   WHEN (3) OUTPUT_CHAR = 'C';
		   WHEN (4) OUTPUT_CHAR = 'D';
		   WHEN (5) OUTPUT_CHAR = 'E';
		   WHEN (6) OUTPUT_CHAR = 'F';
		   WHEN (7) OUTPUT_CHAR = 'G';
		   WHEN (8) OUTPUT_CHAR = 'H';
		   WHEN (9) OUTPUT_CHAR = 'I';
		   WHEN (10) OUTPUT_CHAR = 'J';
		   WHEN (11) OUTPUT_CHAR = 'K';
		   WHEN (12) OUTPUT_CHAR = 'L';
		   WHEN (13) OUTPUT_CHAR = 'M';
		   WHEN (14) OUTPUT_CHAR = 'N';
		   WHEN (15) OUTPUT_CHAR = 'O';
		   WHEN (16) OUTPUT_CHAR = 'P';
		   WHEN (17) OUTPUT_CHAR = 'Q';
		   WHEN (18) OUTPUT_CHAR = 'R';
		   WHEN (19) OUTPUT_CHAR = 'S';
		   WHEN (20) OUTPUT_CHAR = 'T';
		   WHEN (21) OUTPUT_CHAR = 'U';
		   WHEN (22) OUTPUT_CHAR = 'V';
		   WHEN (23) OUTPUT_CHAR = 'U';
		   WHEN (24) OUTPUT_CHAR = 'X';
		   WHEN (25) OUTPUT_CHAR = 'Y';
		   WHEN (26) OUTPUT_CHAR = 'Z';
                   OTHERWISE OUTPUT_CHAR = ' ';
		END;

		RETURN(OUTPUT_CHAR);
        END ASCII_TO_CHAR;
	/*-------------------------------------------------------*/  

程序流程  

该程序的流程基本上是这样的:

  1. 提示用户选择模式(加密/解密)。
  2. 提示用户输入要处理的文本。
  3. 根据用户选择的内容调用加密或解密程序。
  4. 在屏幕上返回操作结果。  

其他概念 

PL/I 是一种非常强大的语言。 它在银行业中的使用主要局限于“获取数据,处理数据,将数据提供给输出”之类的应用程序。 这些应用程序需要包含所用程序的 copybook(通过 %INCLUDE 函数),在调用程序之前填写程序的输入(通过 PROGRAM.IDATA.NAME = 'SKAKOS'; 类型的命令),调用程序(通常使用特定于每个架构的 MACRO),然后处理程序返回的结果。 

祝您编码愉快(?)。

结束; 

相关 PL/I 链接

历史 

初始版本 - 2012/11/27

© . All rights reserved.