這幾天要在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