The following is come code I found I wrote many years ago in Digital VAX MACRO to check passwords for a particular username against a dictionary of words concatenated with a number.
.title check_password $rmsdef $uaidef .psect rw_data rd,wrt,noexe,noshr,long pwdlist_fab: $fab fnm = <sys$library:VMS$PASSWORD_DICTIONARY.DATA> pwdlist_rab: $rab fab = pwdlist_fab,- rop = rah,- ubf = rec_buff,- usz = rec_size rec_size = 32 rec_desc: .word rec_size .word 0 .address rec_buff rec_buff: .blkb rec_size cur_count: .long max_count = 99 num_size = 2 cur_no: .ascid \99\ cur_pwd: .word rec_size+num_size .word 0 .address 10$ 10$: .blkb rec_size+num_size cur_hash: .blkb 8 username: username_len: .word 12 .word 0 .address 10$ 10$: .blkb 12 pwd_list: .word 1 .word uai$_encrypt .address encrypt .address encrypt_len .word 8 .word uai$_pwd .address pwd .address pwd_len .word 2 .word uai$_salt .address salt .address salt_len .word 0 .word 0 encrypt: .byte encrypt_len: .word pwd: .blkb 8 pwd_len: .word salt: .word salt_len: .word usage_msg: .ascid \VMS username must be specificed as a parameter\ .psect code rd,nowrt,exe,shr,long .entry check_password,^m<> ; get username passed on command line - display error if not present pushaq username calls #1,g^lib$get_foreign blbc r0,error_exit pushaw username_len pushaq username pushaq username calls #3,g^str$trim blbc r0,error_exit tstw username_len bnequ get_pwd pushaq usage_msg calls #1,g^lib$put_output brb normal_exit ; retrieve the hashed password from the UAF file get_pwd: $getuai_s usrnam=username,- itmlst=pwd_list blbc r0,error_exit ; open the VMS password dictionary open_dic: $open fab=pwdlist_fab blbc r0,error_exit $connect rab=pwdlist_rab blbc r0,error_exit ; retrieve a word from the dictionary word_loop: $get rab=pwdlist_rab blbs r0,remove_nulls cmpl r0,#rms$_eof beql normal_exit brb error_exit ; get rid of nulls on the end of the record and convert to uppercase remove_nulls: clrw r1 movaq rec_buff,r2 10$: tstb (r2) beql 20$ incw r1 incl r2 brb 10$ 20$: movw r1,rec_desc pushaq rec_desc pushaq rec_desc calls #2,g^str$upcase ; start back at zero for new word clrl cur_count ; append a number to the word append_no: pushl #2 pushl #1 pushaq cur_no pushal cur_count calls #4,g^ots$cvt_l_tu movw #rec_size+num_size,cur_pwd pushaq cur_no pushaq rec_desc pushaq cur_pwd calls #3,g^str$concat blbc r0,error_exit pushaw cur_pwd pushaq cur_pwd pushaq cur_pwd calls #3,g^str$trim ; now we have all the info to hash a password $hash_password_s - pwd=cur_pwd,- alg=encrypt,- salt=salt,- usrnam=username,- hash=cur_hash blbc r0,error_exit ; check if we have a match on the hashed password - if so display cmpl cur_hash,pwd bneq no_match cmpl cur_hash+4,pwd+4 bneq no_match pushaq cur_pwd calls #1,g^lib$put_output brb normal_exit ; loop back 'max_count' times no_match: aoblss #max_count,cur_count,append_no ; loop back for another word brb word_loop normal_exit: movl #1,r0 error_exit: ret .end check_password