func calcResponse(username string, realm string, password string, method string, uri string, nonce string) string {
	calcA1 := func() string {
		encoder := md5.New()
		encoder.Write([]byte(username + ":" + realm + ":" + password))
		return hex.EncodeToString(encoder.Sum(nil))
	}
	calcA2 := func() string {
		encoder := md5.New()
		encoder.Write([]byte(method + ":" + uri))
		return hex.EncodeToString(encoder.Sum(nil))
	}
	encoder := md5.New()
	encoder.Write([]byte(calcA1() + ":" + nonce + ":" + calcA2()))
	return hex.EncodeToString(encoder.Sum(nil))
}
calculates Authorization response https://www.ietf.org/rfc/rfc2617.txt
package sip
import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"regexp"
)
type Authorization struct {
	realm     string
	nonce     string
	algorithm string
	username  string
	password  string
	uri       string
	response  string
	method    string
	other     map[string]string
}
func AuthFromValue(value string) *Authorization {
	auth := &Authorization{
		algorithm: "MD5",
		other:     make(map[string]string),
	}
	re := regexp.MustCompile(`([\w]+)="([^"]+)"`)
	matches := re.FindAllStringSubmatch(value, -1)
	for _, match := range matches {
		switch match[1] {
		case "realm":
			auth.realm = match[2]
		case "algorithm":
			auth.algorithm = match[2]
		case "nonce":
			auth.nonce = match[2]
		case "username":
			auth.username = match[2]
		case "uri":
			auth.uri = match[2]
		case "response":
			auth.response = match[2]
		default:
			auth.other[match[1]] = match[2]
		}
	}
	return auth
}
func (auth *Authorization) Realm() string {
	return auth.realm
}
func (auth *Authorization) Nonce() string {
	return auth.nonce
}
func (auth *Authorization) Algorithm() string {
	return auth.algorithm
}
func (auth *Authorization) Username() string {
	return auth.username
}
func (auth *Authorization) SetUsername(username string) *Authorization {
	auth.username = username
	return auth
}
func (auth *Authorization) SetPassword(password string) *Authorization {
	auth.password = password
	return auth
}
func (auth *Authorization) Uri() string {
	return auth.uri
}
func (auth *Authorization) SetUri(uri string) *Authorization {
	auth.uri = uri
	return auth
}
func (auth *Authorization) SetMethod(method string) *Authorization {
	auth.method = method
	return auth
}
func (auth *Authorization) Response() string {
	return auth.response
}
func (auth *Authorization) SetResponse(response string) {
	auth.response = response
}
func (auth *Authorization) CalcResponse() string {
	return calcResponse(
		auth.username,
		auth.realm,
		auth.password,
		auth.method,
		auth.uri,
		auth.nonce,
	)
}
func (auth *Authorization) String() string {
	return fmt.Sprintf(
		`Digest realm="%s",algorithm=%s,nonce="%s",username="%s",uri="%s",response="%s"`,
		auth.realm,
		auth.algorithm,
		auth.nonce,
		auth.username,
		auth.uri,
		auth.response,
	)
}