这几天要在ABAP中实现 3DES 标准对称加密算法,与其他外部系统进行加密/解密操作。
由于ABAP语言中没有 左移 <<、无符号右移 >>> 操作,只能自己实现
思路:
如果移动的位数bit是字节(8位)的整数倍,则直接使用
SHIFT
<i>
BY
p
PLACES
RIGHT
IN BYTE MODE
.
这样的语句搞定(这样效率会更高),如果非字节整数倍,则需要借助于
SET
BIT
来完成,实现时,要注意整型的字节序格式,本人开发环境是低字节序(低位在前,高位在后),与人的阅读习惯是反的(
但要注意的字节里面还是高位在前,低位在后
),左右位移规则如下(同一种颜色为移动后所在位置):

DATA
:
BEGIN
OF
index_map
OCCURS
0
,
index_inner TYPE i ,
index TYPE i ,
END OF index_map .
index_inner TYPE i ,
index TYPE i ,
END OF index_map .
FORM
init
.
CLEAR : index_map[] .
index_map - index_inner = 1 .
index_map - index = 8 .
APPEND index_map .
index_map - index_inner = 2 .
index_map - index = 7 .
APPEND index_map .
index_map - index_inner = 3 .
index_map - index = 6 .
APPEND index_map .
index_map - index_inner = 4 .
index_map - index = 5 .
APPEND index_map .
index_map - index_inner = 5 .
index_map - index = 4 .
APPEND index_map .
index_map - index_inner = 6 .
index_map - index = 3 .
APPEND index_map .
index_map - index_inner = 7 .
index_map - index = 2 .
APPEND index_map .
index_map - index_inner = 8 .
index_map - index = 1 .
APPEND index_map .
index_map - index_inner = 9 .
index_map - index = 16 .
APPEND index_map .
index_map - index_inner = 10 .
index_map - index = 15 .
APPEND index_map .
index_map - index_inner = 11 .
index_map - index = 14 .
APPEND index_map .
index_map - index_inner = 12 .
index_map - index = 13 .
APPEND index_map .
index_map - index_inner = 13 .
index_map - index = 12 .
APPEND index_map .
index_map - index_inner = 14 .
index_map - index = 11 .
APPEND index_map .
index_map - index_inner = 15 .
index_map - index = 10 .
APPEND index_map .
index_map - index_inner = 16 .
index_map - index = 9 .
APPEND index_map .
index_map - index_inner = 17 .
index_map - index = 24 .
APPEND index_map .
index_map - index_inner = 18 .
index_map - index = 23 .
APPEND index_map .
index_map - index_inner = 19 .
index_map - index = 22 .
APPEND index_map .
index_map - index_inner = 20 .
index_map - index = 21 .
APPEND index_map .
index_map - index_inner = 21 .
index_map - index = 20 .
APPEND index_map .
index_map - index_inner = 22 .
index_map - index = 19 .
APPEND index_map .
index_map - index_inner = 23 .
index_map - index = 18 .
APPEND index_map .
index_map - index_inner = 24 .
index_map - index = 17 .
APPEND index_map .
index_map - index_inner = 25 .
index_map - index = 32 .
APPEND index_map .
index_map - index_inner = 26 .
index_map - index = 31 .
APPEND index_map .
index_map - index_inner = 27 .
index_map - index = 30 .
APPEND index_map .
index_map - index_inner = 28 .
index_map - index = 29 .
APPEND index_map .
index_map - index_inner = 29 .
index_map - index = 28 .
APPEND index_map .
index_map - index_inner = 30 .
index_map - index = 27 .
APPEND index_map .
index_map - index_inner = 31 .
index_map - index = 26 .
APPEND index_map .
index_map - index_inner = 32 .
index_map - index = 25 .
APPEND index_map .
ENDFORM .
CLEAR : index_map[] .
index_map - index_inner = 1 .
index_map - index = 8 .
APPEND index_map .
index_map - index_inner = 2 .
index_map - index = 7 .
APPEND index_map .
index_map - index_inner = 3 .
index_map - index = 6 .
APPEND index_map .
index_map - index_inner = 4 .
index_map - index = 5 .
APPEND index_map .
index_map - index_inner = 5 .
index_map - index = 4 .
APPEND index_map .
index_map - index_inner = 6 .
index_map - index = 3 .
APPEND index_map .
index_map - index_inner = 7 .
index_map - index = 2 .
APPEND index_map .
index_map - index_inner = 8 .
index_map - index = 1 .
APPEND index_map .
index_map - index_inner = 9 .
index_map - index = 16 .
APPEND index_map .
index_map - index_inner = 10 .
index_map - index = 15 .
APPEND index_map .
index_map - index_inner = 11 .
index_map - index = 14 .
APPEND index_map .
index_map - index_inner = 12 .
index_map - index = 13 .
APPEND index_map .
index_map - index_inner = 13 .
index_map - index = 12 .
APPEND index_map .
index_map - index_inner = 14 .
index_map - index = 11 .
APPEND index_map .
index_map - index_inner = 15 .
index_map - index = 10 .
APPEND index_map .
index_map - index_inner = 16 .
index_map - index = 9 .
APPEND index_map .
index_map - index_inner = 17 .
index_map - index = 24 .
APPEND index_map .
index_map - index_inner = 18 .
index_map - index = 23 .
APPEND index_map .
index_map - index_inner = 19 .
index_map - index = 22 .
APPEND index_map .
index_map - index_inner = 20 .
index_map - index = 21 .
APPEND index_map .
index_map - index_inner = 21 .
index_map - index = 20 .
APPEND index_map .
index_map - index_inner = 22 .
index_map - index = 19 .
APPEND index_map .
index_map - index_inner = 23 .
index_map - index = 18 .
APPEND index_map .
index_map - index_inner = 24 .
index_map - index = 17 .
APPEND index_map .
index_map - index_inner = 25 .
index_map - index = 32 .
APPEND index_map .
index_map - index_inner = 26 .
index_map - index = 31 .
APPEND index_map .
index_map - index_inner = 27 .
index_map - index = 30 .
APPEND index_map .
index_map - index_inner = 28 .
index_map - index = 29 .
APPEND index_map .
index_map - index_inner = 29 .
index_map - index = 28 .
APPEND index_map .
index_map - index_inner = 30 .
index_map - index = 27 .
APPEND index_map .
index_map - index_inner = 31 .
index_map - index = 26 .
APPEND index_map .
index_map - index_inner = 32 .
index_map - index = 25 .
APPEND index_map .
ENDFORM .
*&---------------------------------------------------------------------*
*& Form lshfit_i
*&---------------------------------------------------------------------*
* 整型左移
*----------------------------------------------------------------------*
* -->I 待位移的数
* -->PLACES 移几位
* -->I2 位移后的数
*----------------------------------------------------------------------*
FORM lshfit_i USING i TYPE i places TYPE i i2 TYPE i .
DATA : start1 TYPE i , start2 TYPE i .
DATA : b TYPE n .
DATA : i3 TYPE i .
FIELD-SYMBOLS : <i3> TYPE x .
FIELD-SYMBOLS : <i> TYPE x .
FIELD-SYMBOLS : <p> TYPE x .
DATA : _31 ( 4 ) TYPE x , p TYPE i .
p = places .
IF places < 0 .
_31 = '1F000000' .
ASSIGN p TO <p> CASTING .
<p> = <p> BIT-AND _31 .
ENDIF .
i2 = i .
ASSIGN i2 TO <i> CASTING .
IF p = 24 OR p = 16 OR p = 8 .
p = p / 8 .
SHIFT <i> BY p PLACES RIGHT IN BYTE MODE .
ELSE .
ASSIGN i3 TO <i3> CASTING .
start1 = 32 - p .
WHILE start1 >= 1 .
READ TABLE index_map INDEX start1 .
GET BIT index_map - index OF <i> INTO b .
IF b = 1 .
start2 = start1 + p .
READ TABLE index_map INDEX start2 .
SET BIT index_map - index OF <i3> TO b .
ENDIF .
start1 = start1 - 1 .
ENDWHILE .
<i> = <i3> .
ENDIF .
ENDFORM . "lshfit_i
*&---------------------------------------------------------------------*
*& Form rshfit_i
*&---------------------------------------------------------------------*
* 整型右移
*----------------------------------------------------------------------*
* -->I 待位移的数
* -->PLACES 移几位
* -->I2 位移后的数
*----------------------------------------------------------------------*
FORM rshfit_i USING i TYPE i places TYPE i i2 TYPE i .
DATA : start1 TYPE i , start2 TYPE i .
DATA : b TYPE n .
DATA : i3 TYPE i .
FIELD-SYMBOLS : <i3> TYPE x .
FIELD-SYMBOLS : <i> TYPE x .
FIELD-SYMBOLS : <p> TYPE x .
DATA : _31 ( 4 ) TYPE x , p TYPE i .
DATA multiplier TYPE i .
p = places .
IF p < 0 .
_31 = '1F000000' .
ASSIGN p TO <p> CASTING .
<p> = <p> BIT-AND _31 .
ENDIF .
i2 = i .
ASSIGN i2 TO <i> CASTING .
IF p = 24 OR p = 16 OR p = 8 .
p = p / 8 .
SHIFT <i> BY p PLACES LEFT IN BYTE MODE .
ELSE .
IF i >= 0 AND p < 31 .
multiplier = 2 ** p .
i2 = i DIV multiplier .
ELSE .
ASSIGN i3 TO <i3> CASTING .
start1 = p + 1 .
WHILE start1 <= 32 .
READ TABLE index_map INDEX start1 .
GET BIT index_map - index OF <i> INTO b .
IF b = 1 .
start2 = start1 - p .
READ TABLE index_map INDEX start2 .
SET BIT index_map - index OF <i3> TO b .
ENDIF .
start1 = start1 + 1 .
ENDWHILE .
<i> = <i3> .
ENDIF .
ENDIF .
ENDFORM . "rshfit_i
*&---------------------------------------------------------------------*
*& Form c2int
*&---------------------------------------------------------------------*
* 字符转整型
*----------------------------------------------------------------------*
* -->C1 text
* -->I text
*----------------------------------------------------------------------*
FORM c2int USING c1 TYPE c i TYPE i .
FIELD-SYMBOLS <c1> TYPE x .
FIELD-SYMBOLS : <i> TYPE x .
ASSIGN c1 TO <c1> CASTING .
ASSIGN i TO <i> CASTING .
<i> = <c1> .
ENDFORM .
*& Form c2int
*&---------------------------------------------------------------------*
* 字符转整型
*----------------------------------------------------------------------*
* -->C1 text
* -->I text
*----------------------------------------------------------------------*
FORM c2int USING c1 TYPE c i TYPE i .
FIELD-SYMBOLS <c1> TYPE x .
FIELD-SYMBOLS : <i> TYPE x .
ASSIGN c1 TO <c1> CASTING .
ASSIGN i TO <i> CASTING .
<i> = <c1> .
ENDFORM .
*&---------------------------------------------------------------------*
*& Form lshfit_c
*&---------------------------------------------------------------------*
* 字符左移
*----------------------------------------------------------------------*
* -->C1 待位移的字符
* -->PLACES 移几位
* -->I 位移后的结果
*----------------------------------------------------------------------*
FORM lshfit_c USING c1 TYPE c places TYPE i i TYPE i .
PERFORM c2int USING c1 i .
PERFORM lshfit_i USING i places i .
ENDFORM . "lshfit
*&---------------------------------------------------------------------*
*& Form rshfit_c
*&---------------------------------------------------------------------*
* 字符右移
*----------------------------------------------------------------------*
* -->C1 待位移的字符
* -->PLACES 移几位
* -->I 位移后的结果
*----------------------------------------------------------------------*
FORM rshfit_c USING c1 TYPE c places TYPE i i TYPE i .
PERFORM c2int USING c1 i .
PERFORM rshfit_i USING i places i .
ENDFORM . "rshfit_c
*& Form lshfit_c
*&---------------------------------------------------------------------*
* 字符左移
*----------------------------------------------------------------------*
* -->C1 待位移的字符
* -->PLACES 移几位
* -->I 位移后的结果
*----------------------------------------------------------------------*
FORM lshfit_c USING c1 TYPE c places TYPE i i TYPE i .
PERFORM c2int USING c1 i .
PERFORM lshfit_i USING i places i .
ENDFORM . "lshfit
*&---------------------------------------------------------------------*
*& Form rshfit_c
*&---------------------------------------------------------------------*
* 字符右移
*----------------------------------------------------------------------*
* -->C1 待位移的字符
* -->PLACES 移几位
* -->I 位移后的结果
*----------------------------------------------------------------------*
FORM rshfit_c USING c1 TYPE c places TYPE i i TYPE i .
PERFORM c2int USING c1 i .
PERFORM rshfit_i USING i places i .
ENDFORM . "rshfit_c