def detect_span_version_and_encoding(message):
<EOL>if isinstance(message, six.string_types):<EOL><INDENT>if six.PY2:<EOL><INDENT>message = six.b(message)  <EOL><DEDENT>else:<EOL><INDENT>message = message.encode('<STR_LIT:utf-8>')  <EOL><DEDENT><DEDENT>if len(message) < <NUM_LIT:2>:<EOL><INDENT>raise ZipkinError("<STR_LIT>")<EOL><DEDENT>if six.byte2int(message) <= <NUM_LIT:16>:<EOL><INDENT>if six.byte2int(message) == <NUM_LIT:10> and six.byte2int(message[<NUM_LIT:1>:<NUM_LIT:2>]) != <NUM_LIT:0>:<EOL><INDENT>return Encoding.V2_PROTO3<EOL><DEDENT>return Encoding.V1_THRIFT<EOL><DEDENT>str_msg = message.decode('<STR_LIT:utf-8>')<EOL>if str_msg[<NUM_LIT:0>] == '<STR_LIT:[>':<EOL><INDENT>span_list = json.loads(str_msg)<EOL>if len(span_list) > <NUM_LIT:0>:<EOL><INDENT>for span in span_list:<EOL><INDENT>if any(word in span for word in _V2_ATTRIBUTES):<EOL><INDENT>return Encoding.V2_JSON<EOL><DEDENT>elif (<EOL>'<STR_LIT>' in span or<EOL>(<EOL>'<STR_LIT>' in span and<EOL>'<STR_LIT>' in span['<STR_LIT>']<EOL>)<EOL>):<EOL><INDENT>return Encoding.V1_JSON<EOL><DEDENT><DEDENT>return Encoding.V2_JSON<EOL><DEDENT><DEDENT>raise ZipkinError("<STR_LIT>")<EOL>
Returns the span type and encoding for the message provided.

    The logic in this function is a Python port of
    https://github.com/openzipkin/zipkin/blob/master/zipkin/src/main/java/zipkin/internal/DetectingSpanDecoder.java

    :param message: span to perform operations on.
    :type message: byte array
    :returns: span encoding.
    :rtype: Encoding