diff --git a/layouts/partials/shortlink.txt b/layouts/partials/shortlink.txt index 4720e591..4c007a8a 100644 --- a/layouts/partials/shortlink.txt +++ b/layouts/partials/shortlink.txt @@ -1,6 +1,30 @@ {{- $shortlink := .Params.shortlink -}} -{{- if not $shortlink -}} - {{/* TODO: Could convert to base36 to reduce size by 2 chars */}} - {{- $shortlink = printf "b/%s" (substr (.RelPermalink | crypto.MD5 ) 0 10) -}} +{{- $chars := split "123456789bcdfghjkmnpqrstuvwxyz" "" -}}{{/* Omit vowels and confusing characters to prevent accidental spelling of words */}} +{{- $base := len $chars -}} +{{- $size := 8 -}}{{/* 8 chars with 30 possibilities means 0.0091% chance of collision with 10k posts; I currently have 3,213 */}} +{{- if and (not $shortlink) true -}}{{/* .IsPage Don't make dynamic shortlinks for list taxonomy/list/non-regular pages */}} + {{- $hex := .RelPermalink | crypto.MD5 -}} + + {{- $idx := 0 -}} + {{- $n := 0 -}} + {{- $enc := slice -}} + + {{- range (split $hex "") | collections.Reverse -}} + {{- $dec := int (printf "0x%s" .) -}} + {{- $n = add $dec (mul $n 16) -}} + + {{- range seq 2 -}} + {{- if le $n $base -}}{{ break }}{{- end -}} + + {{- $amt := (mod $n $base) -}} + {{- $char := index $chars $amt }} + {{- $enc = $enc | append $char -}} + {{- $n = div $n $base -}} + {{- end -}} + + {{- if ge (len $enc) $size -}}{{- break -}}{{- end -}} + {{- end -}} + + {{- $shortlink = printf "b/%s" (delimit ($enc | collections.Reverse) "") -}} {{- end -}} {{- $shortlink -}} \ No newline at end of file