Tarsnap does this. My project (ddar) does the same.
How does ddar do it?
Blocks whose boundaries are determined by this algorithm are hashed (SHA256 currently). The hash is used to key each block in a reference-counted key/value store.
Then each archive member is just a list of block hashes.
There are implementations in Lua, Java, and C.