def validate(self, ticket, client_ip=None, now=None, encoding='<STR_LIT:utf-8>'):
parts = self.parse(ticket)<EOL>new_ticket = self.new(*(parts[<NUM_LIT:1>:]), client_ip=client_ip, encoding=encoding)<EOL>if new_ticket[:self._hash.digest_size * <NUM_LIT:2>] != parts.digest:<EOL><INDENT>raise TicketDigestError(ticket)<EOL><DEDENT>if now is None:<EOL><INDENT>now = time.time()<EOL><DEDENT>if parts.valid_until <= now:<EOL><INDENT>raise TicketExpired(ticket)<EOL><DEDENT>return parts<EOL>
Validates the passed ticket, , raises a TicketError
        on failure

        Args:
            ticket: String value (possibly generated by new function)
            client_ip: Optional IPAddress of client, should be passed if the
                ip address was passed on ticket creation.
            now: Optional (defaults to time.time()) time to use when
                validating ticket date

        Returns:
            Ticket a TicketInfo tuple containing the users authentication details on
            success

        Raises:
            TicketParseError: Invalid ticket format
            TicketDigestError: Digest is incorrect (ticket data was modified)
            TicketExpired: Ticket has passed expiration date