*&---------------------------------------------------------------------* 
*& Report Z_XL_SLMK
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT Z_XL_SLMK.

.
PARAMETERS : P_SID(3 ) TYPE C ,
P_SYSNO(2 ),
P_SERVER(10 ),
P_INSTNO(10 ).
DATA :
P_PF_SID(3 ), " SID of SAP system
P_PF_SYSNO(2 ), " Central Instance Number
P_PF_SERVER(10 ), " Message Server Host Name, Less than 10 chars
P_PF_INSTNO(10 ), " Installation Number
P_PF_VALUE(20 ). " SolMan Key for installation and upgrade
start-of -SELECTION.
P_PF_SID = P_SID.
P_PF_SYSNO = P_SYSNO.
P_PF_SERVER = P_SERVER .
P_PF_INSTNO = P_INSTNO .
PERFORM get_sp_value USING P_PF_SID
P_PF_SYSNO
P_PF_SERVER
P_PF_INSTNO
CHANGING P_PF_VALUE.
WRITE : / 'KEY:' , P_PF_VALUE .
FORM get_sp_value USING P_PF_SID
P_PF_SYSNO
P_PF_SERVER
P_PF_INSTNO
CHANGING P_PF_VALUE.
CONSTANTS : lc_part_len TYPE i VALUE 5 ,
lc_pw_len TYPE i VALUE 10 ,
lc_allowed_chars(38 ) TYPE c VALUE
'-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_' .

data : lf_string(20 ) type c ,
lf_key type i ,
* ls_key type dswpclientkey,
lf_part(lc_part_len) type c ,
lf_finalf(lc_pw_len) type c ,
lf_finalx type xstring,
lf_xbuffer type xstring,
lf_opf(10 ) type c ,
lf_langu like sy-langu,
lf_subrc like sy-subrc,
lf_len type i ,
lo_conv_to_x TYPE REF TO cl_abap_conv_out_ce.
clear : lf_string, lf_finalx, lf_opf.
concatenate p_pf_sid p_pf_sysno p_pf_server into lf_string.
* Large letters only
translate lf_string to upper case .
lf_langu = sy-langu.
SET LOCALE LANGUAGE 'E' .
lo_conv_to_x = cl_abap_conv_out_ce=>create( encoding = '1100' ).
lf_len = STRLEN ( lf_string ).
IF lf_string(lf_len) CN lc_allowed_chars.
else .
* Fold the input string to a lc_part_len long string
WHILE lf_len > 0 .
lf_part = lf_string(lc_part_len).
SHIFT lf_string BY lc_part_len PLACES .
lf_len = STRLEN ( lf_string ).
CALL METHOD lo_conv_to_x->reset.
CALL METHOD lo_conv_to_x->write( data = lf_part n = -1 ).
lf_xbuffer = lo_conv_to_x->get_buffer( ).
lf_finalx = lf_finalx BIT -XOR lf_xbuffer.
ENDWHILE .
lf_key = 12 .
PERFORM scramble USING lf_finalx
lf_key
lc_part_len
CHANGING lf_finalf
lf_subrc.
if lf_subrc EQ 0 .
p_pf_value = lf_finalf .
endif .
* if not lf_finalf is initial.
* p_pf_value = lf_finalf.
* ls_key-dbid = p_pf_sid.
* ls_key-instno = p_pf_instno.
* ls_key-bundle_id = 'SM_KEY'.
* ls_key-service_key = lf_finalf.
* if not p_pf_instno is initial.
* insert dswpclientkey from ls_key.
* if sy-subrc <> 0.
* update dswpclientkey from ls_key.
* endif.
* endif.
* else.
* clear p_pf_value.
* endif.
endif .
ENDFORM . " get_sp_value
FORM scramble USING iv_xstring TYPE xstring
iv_key TYPE i
iv_src_len TYPE i
CHANGING lf_finalf
lf_subrc LIKE sy-subrc.
CONSTANTS : lc_max_len TYPE i VALUE 20 ,
lc_mask(4 ) TYPE x VALUE '0000003F' ,
lc_random(64 ) TYPE x VALUE
'F0ED53B83244F1F876C67959FD4F13A2' &
'C15195EC5483C234774943A27DE26596' &
'5E5398789A17A33CD383A8B829FBDCA5' &
'55D702778413ACDDF9B83116610E6DFA' .
DATA : lv_key_index(4 ) TYPE x ,
lv_rand_index(4 ) TYPE x ,
lv_xkey(4 ) TYPE x ,
lv_xkey_shl_1(4 ) TYPE x ,
lv_xkey_shr_5(4 ) TYPE x ,
lv_scramble_byte TYPE x ,
lv_dest(lc_max_len) TYPE x ,
lv_index TYPE i ,
lv_len TYPE i .

IF iv_src_len EQ 0 . EXIT . ENDIF .
lv_len = XSTRLEN ( iv_xstring ).
IF iv_src_len GT lc_max_len OR
iv_src_len GT lv_len.
lf_subrc = 2 .
EXIT .
ENDIF .
lv_xkey = iv_key.
lv_xkey_shl_1 = iv_key * 2 .
lv_xkey_shr_5 = iv_key DIV 32 .
lv_rand_index = lv_xkey BIT -XOR lv_xkey_shr_5 BIT -XOR lv_xkey_shl_1.
lv_rand_index = lv_rand_index BIT -AND lc_mask.
lv_index = 0 .
DO iv_src_len TIMES .
CATCH SYSTEM-EXCEPTIONS compute_int_times_overflow = 1 .
lv_key_index = ( iv_key * lv_index * lv_index ) - lv_index.
ENDCATCH.
IF sy-subrc <> 0 .
lf_subrc = 1 .
EXIT .
ENDIF .
lv_scramble_byte = lc_random+lv_rand_index(1 ) BIT -XOR
lv_key_index+3 (1 ).
lv_dest+lv_index(1 ) = iv_xstring+lv_index(1 ) BIT -XOR
lv_scramble_byte.
lv_index = lv_index + 1 .
lv_rand_index = lv_rand_index + 1 .
lv_rand_index = lv_rand_index BIT -AND lc_mask.
ENDDO .
IF lf_subrc <> 0 .
EXIT .
ENDIF .
WRITE lv_dest(iv_src_len) TO lf_finalf.
ENDFORM