For classifying error reports, I need to generate an ID from an exception. That ID should be(more or less) uniquea short alpha numeric stringequal for equivalent exceptions (even on different systems)The following code seems to do the job:    public static string GetExceptionID(this Exception ex)    {        if (ex == null) return 0000;        int hash = 31;        var innerException = ex;        while (innerException != null)        {            hash ^= GetHash(innerException.GetType().ToString());            hash ^= innerException.StackTrace                                  .Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)                                  // If *.pdb file is provided, the file and line no. (e.g. ... in C:\Path...) is part of the stacktrace.                                  // The next line cutting off that part                                  .Select(line => line.Substring(0, line.IndexOf( in ) < 0 ? line.Length : line.IndexOf( in )))                                  .Aggregate(31, (currentHash, val) => currentHash ^= val.GetHash());            innerException = innerException.InnerException;        }        return Convert.ToBase64String(BitConverter.GetBytes(hash))            .Replace('+', 'P')            .Replace('-', 'M')            .Replace(=, )            .ToUpper();    }    // https://en.wikipedia.org/wiki/Jenkins_hash_function    private static int GetHash(this string str)    {        if (str == null) return 1;        int hash = 31;        foreach (char c in str)        {            unchecked            {                hash += c;                hash += hash << 10;                hash ^= hash >> 6;            }        }        hash += hash << 3;        hash ^= hash >> 11;        hash += hash << 15;        return hash;    }Do you see any problems with the code?
Generating unique ID of an exception
c#;exception;hashcode
Stack traceI think you shouldn't work with the stack string but retrieve the stack and go through each frame yourself. I find it would make the analysis more reliable and you could get the information you need without extracting it from the string because you would have direct access to each part.private static IEnumerable<dynamic> GetStackTrace(this Exception exception){    var stackTrace = new StackTrace(exception, true);    var stackFrames = stackTrace.GetFrames();    var result = stackFrames?.Select(sf => new    {        Caller = (sf.GetMethod() as MethodInfo)?.ToShortString() ?? string.Empty,        FileName = Path.GetFileName(sf.GetFileName()),        LineNumber = sf.GetFileLineNumber(),    });}This snippet comes from my Exception prettyfier.Other suggestionsIt would be a good idea to split this method into three or four methods.the first one gets you the information you need from the stack - you could implement it either based on the string or on the raw stack tracethe second one would encode the data as Base64Stringthe third and last one would clean-up or encode the string generated by the second onethe fourth could be a helper encapsulating the three other methodsExample:var ex.ToExceptionId()wherepublic static string ToExceptionId(this Exception ex){    return ex.GetStackTrace().ToBase64String().EncodeBase64String();}Now you can test and maintain each part of the exception id creation separately.