Computes the altitude from DF4 or DF20 message, bit 20-32.
    credit: @fbyrkjeland

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        int: altitude in ft

def altcode(msg):
    """Computes the altitude from DF4 or DF20 message, bit 20-32.
    credit: @fbyrkjeland

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        int: altitude in ft
    """

    if df(msg) not in [0, 4, 16, 20]:
        raise RuntimeError("Message must be Downlink Format 0, 4, 16, or 20.")

    # Altitude code, bit 20-32
    mbin = hex2bin(msg)

    mbit = mbin[25]   # M bit: 26
    qbit = mbin[27]   # Q bit: 28


    if mbit == '0':         # unit in ft
        if qbit == '1':     # 25ft interval
            vbin = mbin[19:25] + mbin[26] + mbin[28:32]
            alt = bin2int(vbin) * 25 - 1000
        if qbit == '0':     # 100ft interval, above 50175ft
            C1 = mbin[19]
            A1 = mbin[20]
            C2 = mbin[21]
            A2 = mbin[22]
            C4 = mbin[23]
            A4 = mbin[24]
            # _ = mbin[25]
            B1 = mbin[26]
            # D1 = mbin[27]     # always zero
            B2 = mbin[28]
            D2 = mbin[29]
            B4 = mbin[30]
            D4 = mbin[31]

            graystr =  D2 + D4 + A1 + A2 + A4 + B1 + B2 + B4 + C1 + C2 + C4
            alt = gray2alt(graystr)

    if mbit == '1':         # unit in meter
        vbin = mbin[19:25] + mbin[26:31]
        alt = int(bin2int(vbin) * 3.28084)  # convert to ft

    return alt