import hashlib

import numpy as np

import scipy.sparse


def hash_array_or_matrix(X: np.ndarray) -> str:
    m = hashlib.md5()

    if hasattr(X, "iloc"):
        X = X.to_numpy()

    if scipy.sparse.issparse(X):
        m.update(X.indices)
        m.update(X.indptr)
        m.update(X.data)
        m.update(str(X.shape).encode('utf8'))
    else:
        if X.flags['C_CONTIGUOUS']:
            m.update(X.data)
            m.update(str(X.shape).encode('utf8'))
        else:
            X_tmp = np.ascontiguousarray(X.T)
            m.update(X_tmp.data)
            m.update(str(X_tmp.shape).encode('utf8'))

    hash = m.hexdigest()
    return hash
