Change 24-bit hash to 22-bit hash.

This commit is contained in:
Joe Taylor 2018-06-28 11:48:42 -04:00
parent 0b8d2b620f
commit 1d0ffcfdca
8 changed files with 102 additions and 39 deletions

View File

@ -35,10 +35,12 @@ NB: three 74-bit message types and two 71-bit message subtypes are still TBD.
Facts about the 28-bit integers used to encode standard callsigns:
2^28 = 268,435,456 Available values
37*36*10*27*27*27 = 262,177,560 Needed for standard callsign structure
11*10*10*27*27*27 = 21,651,300 nnnaaa, _nnaaa (n=digit, a=letter or blank)
2^24 = 16,777,216 available for 24-bit hash code
4,874,084 available for CQ, CQ xx, CQ nnn, QRZ, etc.
37*36*10*27*27*27 = 262,177,560 Used for standard callsigns
-----------
6,257,896 Difference
2^22 = 4,194,304 Used for 22-bit hash code
-----------
2,063,592 available for CQ, CQ xx, CQ nnn, QRZ, etc.
Further details:

View File

@ -2,4 +2,4 @@ gfortran -c ../packjt.f90
gfortran -o encode77 -fbounds-check -Wall -Wno-conversion -Wno-real-q-constant \
encode77.f90 ../deg2grid.f90 ../grid2deg.f90 ../fix_contest_msg.f90 \
../to_contest_msg.f90 ../fmtmsg.f90 ../azdist.f90 ../geodist.f90 \
ihashcall.f90 hash10.f90 hash13.f90 hash24.f90 packjt.o
ihashcall.f90 hash10.f90 hash13.f90 hash22.f90 packjt.o

View File

@ -1,2 +1,2 @@
gfortran -o test28 -fbounds-check -Wall -Wno-conversion test28.f90 pack28.f90 \
unpack28.f90 ihashcall.f90 hash24.f90
unpack28.f90 ihashcall.f90 hash22.f90

View File

@ -1,6 +1,6 @@
subroutine hash24(n24,c13,isave)
subroutine hash22(n22,c13,isave)
parameter (NMAX=20)
parameter (NMAX=22)
character*13 c13,callsign(NMAX)
integer ihash(NMAX)
logical first
@ -15,15 +15,16 @@ subroutine hash24(n24,c13,isave)
if(isave.ge.0) then
do i=1,NMAX
if(ihash(i).eq.n24) go to 900 !This one is already in the list
if(ihash(i).eq.n22) go to 900 !This one is already in the list
enddo
ihash(NMAX:2:-1)=ihash(NMAX-1:1:-1)
callsign(NMAX:2:-1)=callsign(NMAX-1:1:-1)
ihash(1)=n24
ihash(1)=n22
callsign(1)=c13
else
c13='<...>'
do i=1,NMAX
if(ihash(i).eq.n24) then
if(ihash(i).eq.n22) then
c13=callsign(i)
go to 900
endif
@ -31,4 +32,4 @@ subroutine hash24(n24,c13,isave)
endif
900 return
end subroutine hash24
end subroutine hash22

View File

@ -1,9 +1,9 @@
subroutine pack28(c13,n28)
! Pack a special token, a 24-bit hash code, or a valid base call into a 28-bit
! Pack a special token, a 22-bit hash code, or a valid base call into a 28-bit
! integer.
parameter (NTOKENS=4874084,MAX24=16777216)
parameter (NTOKENS=2063592,MAX22=4194304)
integer nc(6)
logical is_digit,is_letter
character*13 c13
@ -79,9 +79,9 @@ subroutine pack28(c13,n28)
! Check for <...> callsign
if(c13(1:1).eq.'<')then
n24=ihashcall(c13,24)
call hash24(n24,c13,1) !Save (key,value) in hash table
n28=NTOKENS + n24
n22=ihashcall(c13,22)
call hash22(n22,c13,1) !Save (key,value) in hash table
n28=NTOKENS + n22
go to 900
endif
@ -91,9 +91,9 @@ subroutine pack28(c13,n28)
do i=n,2,-1
if(is_digit(c13(i:i))) exit
enddo
iarea=i
npdig=0
nplet=0
iarea=i !Call-area digit
npdig=0 !Digits before call area
nplet=0 !Letters before call area
do i=1,iarea-1
if(is_digit(c13(i:i))) npdig=npdig+1
if(is_letter(c13(i:i))) nplet=nplet+1
@ -104,10 +104,11 @@ subroutine pack28(c13,n28)
enddo
if(iarea.lt.2 .or. iarea.gt.3 .or. nplet.eq.0 .or. &
npdig.ge.iarea-1 .or. nslet.gt.3) then
! Treat this as a nonstandard callsign: compute its 24-bit hash
n24=ihashcall(c13,24)
call hash24(n24,c13,1) !Save (key,value) in hash table
n28=NTOKENS + n24
! print*,'a',npdig,nplet,iarea
! Treat this as a nonstandard callsign: compute its 22-bit hash
n22=ihashcall(c13,22)
call hash22(n22,c13,1) !Save (key,value) in hash table
n28=NTOKENS + n22
go to 900
endif
@ -123,7 +124,8 @@ subroutine pack28(c13,n28)
i6=index(a4,callsign(6:6))-1
n28=36*10*27*27*27*i1 + 10*27*27*27*i2 + 27*27*27*i3 + 27*27*i4 + &
27*i5 + i6
n28=n28 + NTOKENS + MAX24
n28=n28 + NTOKENS + MAX22
900 return
900 n28=iand(n28,2**28-1)
return
end subroutine pack28

View File

@ -1,21 +1,43 @@
program test28
character*13 call_0,call_1,base_call_1
parameter (NTOKENS=2063592,MAX22=4194304)
character*13 call_0,call_1,bare_call_1
character*1 cerr
do iline=1,999
read(*,'(a13)',end=999) call_0
nargs=iargc()
open(10,file='test28.txt',status='old')
write(*,1000)
1000 format('Encoded text Recovered text n28 Err? Type'/60('-'))
do iline=1,999999
if(nargs.eq.0) then
read(10,'(a13)',end=999) call_0
else
call getarg(1,call_0)
endif
if(call_0.eq.' ') exit
if(call_0(1:3).eq.'CQ ' .and. call_0(4:4).ne.' ') call_0(3:3)='_'
call_1=' '
call pack28(call_0,n28)
call unpack28(n28,call_1)
cerr=' '
if(call_0.ne.call_1) cerr='*'
if(call_1(1:1).eq.'<') then
i=index(call_1,'>')
base_call_1=call_1(2:i-1)//' '
bare_call_1=call_1(2:i-1)//' '
endif
if(call_0.eq.base_call_1) cerr=' '
write(*,1010) call_0,n28,cerr,call_1
1010 format(a13,i12,2x,a1,2x,a13a13)
if(call_0.eq.bare_call_1) cerr=' '
if(call_0(1:3).eq.'CQ_') call_0(3:3)=' '
if(call_1(1:3).eq.'CQ_') call_1(3:3)=' '
if(n28.lt.NTOKENS) write(*,1010) call_0,call_1,n28,cerr
1010 format(a13,2x,a13,i10,2x,a1,2x,'Special token')
if(n28.ge.NTOKENS .and. n28.lt.NTOKENS+MAX22) write(*,1012) call_0, &
call_1,n28,cerr
1012 format(a13,2x,a13,i10,2x,a1,2x,'22-bit hash')
if(n28.ge.NTOKENS+MAX22) write(*,1014) call_0,call_1,n28,cerr
1014 format(a13,2x,a13,i10,2x,a1,2x,'Standard callsign')
if(nargs.gt.0) exit
enddo
999 end program test28

36
lib/77bit/test28.txt Normal file
View File

@ -0,0 +1,36 @@
DE
QRZ
CQ
CQ_000
CQ_001
CQ_999
CQ_A
CQ_Z
CQ_AA
CQ_ZZ
CQ_AAA
CQ_ZZZ
CQ_AAAA
CQ_ZZZZ
EI30T
YW18FIFA
<KH1/KH7Z>
ZS9YOTA
YB50ST
999ABC
HA70BAY
WB2000XYZ
WB2000XYZABCD
ZM90DX
<VP2E/KA1ABC>
HB9GOLD
A0A
K1ABC
K1JT
5B1ABC
9Y4AB
9Y4XYZ
KA1ABC
KA1JT
WB9XYZ
ZZ9ZZZ

View File

@ -1,6 +1,6 @@
subroutine unpack28(n28_0,c13)
parameter (NTOKENS=4874084,MAX24=16777216)
parameter (NTOKENS=2063592,MAX22=4194304)
integer nc(6)
character*13 c13
character*37 c1
@ -41,15 +41,15 @@ subroutine unpack28(n28_0,c13)
endif
endif
n28=n28-NTOKENS
if(n28.lt.MAX24) then
! This is a 24-bit hash of a callsign
n24=n28
call hash24(n24,c13,-1) !Retrieve callsign from hash table
if(n28.lt.MAX22) then
! This is a 22-bit hash of a callsign
n22=n28
call hash22(n22,c13,-1) !Retrieve callsign from hash table
go to 900
endif
! Standard callsign
n=n28 - MAX24
n=n28 - MAX22
i1=n/(36*10*27*27*27)
n=n-36*10*27*27*27*i1
i2=n/(10*27*27*27)