As for other mathematical ways, you can use some variants of the Fourier transformation. My Fast Japh does that, for example. It's called "fast" because for long strings it would be much faster to do than the simple polynomial thing.
Now, as is, that japh encodes and decodes the string again so it's not much useful, but I've converted it to a japh that does the decoding only:
use warnings; use strict;
or$,[uc]+=$,[2**$,+$_]-=($,[lc]*=2)/2for 0..31}print chr($_/16)for@,
Update: fixed code, which accidentally had its output appended to it.