You can see the CDDL spec for full details: https://github.com/input-output-hk/cardano-ledger/blob/master/eras/shelley/test-suite/cddl-files/shelley.cddl
In the case of a payment base address (the most common address on the chain at the moment), the address when converted from bech32 -> hex will have a prefix of 00 (on testnet, 01 on mainnet), followed by the payment credential, followed by the stake credential. The payment and stake credentials are hashes of those pubkeys.
Here's an example output (and cardano-address inspect output so you can see an example matching the pieces):
cardano-address address inspect <<< addr_test1qrkgclg3rsz8v8hnv2sqxmfk3yl87p9dme906h4ru859j9z076sepqv0ms7pud50lrgfh3e72jrysy5wawg4hqgmzfrsvgallu
{
"stake_reference": "by value",
"stake_key_hash_bech32": "stake_vkh1flm2ryyp3lwrc83k3ludpx788e2gvjqj3m4ezkuprvfywejlp0j",
"stake_key_hash": "4ff6a190818fdc3c1e368ff8d09bc73e548648128eeb915b811b1247",
"spending_key_hash_bech32": "addr_test1ajx86yguq3mpaumz5qpk6d5f8elsftw7ft74aglpapv3g07qz53",
"address_style": "Shelley",
"spending_key_hash": "ec8c7d111c04761ef362a0036d36893e7f04adde4afd5ea3e1e85914",
"network_tag": 0
bech32 <<< addr_test1qrkgclg3rsz8v8hnv2sqxmfk3yl87p9dme906h4ru859j9z076sepqv0ms7pud50lrgfh3e72jrysy5wawg4hqgmzfrsvgallu
00ec8c7d111c04761ef362a0036d36893e7f04adde4afd5ea3e1e859144ff6a190818fdc3c1e368ff8d09bc73e548648128eeb915b811b1247