Skip to main content
2 of 2
added 34 characters in body
Neil
  • 177.3k
  • 12
  • 74
  • 281

JavaScript (Node.js), 131 128 bytes

s=>unescape(s.replace(/B.(D.)?/g,(f,s)=>(-~g(f[1])*4*!!s+g((s||f)[1])).toString(16),g=c=>'IAOU'.search(c)).replace(/../g,'%$&'))

Try it online! Link includes test cases. Alternative version, also 131 bytes:

s=>unescape(s.replace(/B.(D.)?/g,s=>(-~g(s[1])*4*!!s[3]+g(s[3]||s[1])).toString(16),g=c=>'IAOU'.search(c)).replace(/../g,'%$&'))

Try it online! Link includes test cases. Edit: Saves 3 bytes thanks to @Shaggy.

Neil
  • 177.3k
  • 12
  • 74
  • 281