public function encode(
        $username,
        $nt_domain,
        $client_hostname,
        CredentialInterface $credential,
        ServerChallenge $server_challenge
    ) {
        $negotiate_flags = $server_challenge->getNegotiateFlags();
        $server_challenge_nonce = $server_challenge->getNonce();
        $target_name = $this->identifyTargetName($username, $nt_domain, $server_challenge);

        $client_challenge = null;

        // If extended session security is negotiated
        if ((NegotiateFlag::NEGOTIATE_EXTENDED_SESSION_SECURITY & $negotiate_flags)
            === NegotiateFlag::NEGOTIATE_EXTENDED_SESSION_SECURITY) {
            // Generate a client challenge
            $client_challenge = $this->random_byte_generator->generate(static::CLIENT_CHALLENGE_LENGTH);
        }

        $lm_hash = null;
        $nt_hash = null;
        $lm_challenge_response = null;
        $nt_challenge_response = null;

        $calculate_lm_response = true;
        $calculate_nt_response = true;

        if ($credential->isPlaintext()) {
            $lm_hash = $this->lm_hasher->hash($credential);
            $nt_hash = $this->nt_hasher->hash($credential);
        } elseif ($credential instanceof HashCredentialInterface) {
            switch ($credential->getType()) {
                case HashType::LM:
                    $lm_hash = $credential;
                    $calculate_nt_response = false;
                    break;
                case HashType::NT_V1:
                    $nt_hash = $credential;
                    $calculate_lm_response = false;
                    break;
                default:
                    throw new InvalidArgumentException('Unsupported hash credential type');
            }
        }

        if (null !== $nt_hash && $calculate_nt_response) {
            $nt_challenge_response = $this->calculateNtResponse(
                $nt_hash,
                $client_challenge,
                $server_challenge_nonce
            );
        }

        // If we have a client challenge, extended session security must be negotiated
        if (null !== $client_challenge) {
            // Set the LM challenge response to the client challenge, null-padded to the expected length
            $lm_challenge_response = str_pad(
                $client_challenge,
                static::LM_RESPONSE_LENGTH,
                static::NULL_PAD_CHARACTER
            );
        } elseif (null !== $lm_hash && $calculate_lm_response) {
            $lm_challenge_response = $this->calculateLmResponse(
                $lm_hash,
                $client_challenge,
                $server_challenge_nonce
            );
        } else {
            // According to the spec, we're supposed to use the NT challenge response for the LM challenge response,
            // if an LM challenge response isn't calculated
            $lm_challenge_response = $nt_challenge_response;
        }

        // TODO: Generate an encrypted random session key
        $session_key = '';

        return $this->encodeBinaryMessageString(
            $negotiate_flags,
            $lm_challenge_response,
            $nt_challenge_response,
            $target_name,
            $username,
            $client_hostname,
            $session_key
        );
    }
public function encode(
        $username,
        $nt_domain,
        $client_hostname,
        CredentialInterface $credential,
        ServerChallenge $server_challenge
    ) {
        $negotiate_flags = $server_challenge->getNegotiateFlags();
        $server_challenge_nonce = $server_challenge->getNonce();
        $target_name = $this->identifyTargetName($username, $nt_domain, $server_challenge);

        $client_challenge = null;

        // If extended session security is negotiated
        if ((NegotiateFlag::NEGOTIATE_EXTENDED_SESSION_SECURITY & $negotiate_flags)
            === NegotiateFlag::NEGOTIATE_EXTENDED_SESSION_SECURITY) {
            // Generate a client challenge
            $client_challenge = $this->random_byte_generator->generate(static::CLIENT_CHALLENGE_LENGTH);
        }

        $lm_hash = null;
        $nt_hash = null;
        $lm_challenge_response = null;
        $nt_challenge_response = null;

        $calculate_lm_response = true;
        $calculate_nt_response = true;

        if ($credential->isPlaintext()) {
            $lm_hash = $this->lm_hasher->hash($credential);
            $nt_hash = $this->nt_hasher->hash($credential);
        } elseif ($credential instanceof HashCredentialInterface) {
            switch ($credential->getType()) {
                case HashType::LM:
                    $lm_hash = $credential;
                    $calculate_nt_response = false;
                    break;
                case HashType::NT_V1:
                    $nt_hash = $credential;
                    $calculate_lm_response = false;
                    break;
                default:
                    throw new InvalidArgumentException('Unsupported hash credential type');
            }
        }

        if (null !== $nt_hash && $calculate_nt_response) {
            $nt_challenge_response = $this->calculateNtResponse(
                $nt_hash,
                $client_challenge,
                $server_challenge_nonce
            );
        }

        // If we have a client challenge, extended session security must be negotiated
        if (null !== $client_challenge) {
            // Set the LM challenge response to the client challenge, null-padded to the expected length
            $lm_challenge_response = str_pad(
                $client_challenge,
                static::LM_RESPONSE_LENGTH,
                static::NULL_PAD_CHARACTER
            );
        } elseif (null !== $lm_hash && $calculate_lm_response) {
            $lm_challenge_response = $this->calculateLmResponse(
                $lm_hash,
                $client_challenge,
                $server_challenge_nonce
            );
        } else {
            // According to the spec, we're supposed to use the NT challenge response for the LM challenge response,
            // if an LM challenge response isn't calculated
            $lm_challenge_response = $nt_challenge_response;
        }

        // TODO: Generate an encrypted random session key
        $session_key = '';

        return $this->encodeBinaryMessageString(
            $negotiate_flags,
            $lm_challenge_response,
            $nt_challenge_response,
            $target_name,
            $username,
            $client_hostname,
            $session_key
        );
    }
{@inheritDoc}