Something I just realized about the previous algorithm:
Passwords created by a human do not necessarily correspond to data sequences. For example, mypass3 might break down into indices 12, 34, 3. There might not be 34 words in your list.
You can solve this using mod, but there is a catch. Bear with me.
Take the sequence 12, 34, 3 and take each one mod 20 to get
12, 14, 3
Then convert to the valid data sequence, say 'bonk, bing, bop'
The catch is as follows:
say 12, 14, 3 equates to 'C6&7fG#'
Then, reconstructing the password from the data will give this value and not 'mypass3'
To fix this:
Store only the generated password with each user, e.g. C6&7fG#
When the user logs in with 'mypass3', compute the real password associated with it.
Although this works, multiple passwords will work for each user. (mypass3, TBh#%( , and g4Gqj might all equate to C6&7fG#.)
Then again, this is only the first idea that popped into my head...
-HavaTheJut