      """
      if "CSRF_COOKIE" not in request.META:
          request.META["CSRF_COOKIE"] = _get_new_csrf_key()
      request.META["CSRF_COOKIE_USED"] = True
      return request.META["CSRF_COOKIE"]
  
  
  def rotate_token(request):
      """
      Changes the CSRF token in use for a request - should be done on login
 
</s> remove         request.META["CSRF_COOKIE"] = _get_new_csrf_key()
 </s> add         csrf_secret = _get_new_csrf_string()
        request.META["CSRF_COOKIE"] = _salt_cipher_secret(csrf_secret)
    else:
        csrf_secret = _unsalt_cipher_token(request.META["CSRF_COOKIE"]) </s> remove def _get_new_csrf_key():
    return get_random_string(CSRF_KEY_LENGTH)
 </s> add def _get_new_csrf_string():
    return get_random_string(CSRF_SECRET_LENGTH, allowed_chars=CSRF_ALLOWED_CHARS)


def _salt_cipher_secret(secret):
    """
    Given a secret (assumed to be a string of CSRF_ALLOWED_CHARS), generate a
    token by adding a salt and using it to encrypt the secret.
    """
    salt = _get_new_csrf_string()
    chars = CSRF_ALLOWED_CHARS
    pairs = zip((chars.index(x) for x in secret), (chars.index(x) for x in salt))
    cipher = ''.join(chars[(x + y) % len(chars)] for x, y in pairs)
    return salt + cipher


def _unsalt_cipher_token(token):
    """
    Given a token (assumed to be a string of CSRF_ALLOWED_CHARS, of length
    CSRF_TOKEN_LENGTH, and that its first half is a salt), use it to decrypt
    the second half to produce the original secret.
    """
    salt = token[:CSRF_SECRET_LENGTH]
    token = token[CSRF_SECRET_LENGTH:]
    chars = CSRF_ALLOWED_CHARS
    pairs = zip((chars.index(x) for x in token), (chars.index(x) for x in salt))
    secret = ''.join(chars[x - y] for x, y in pairs)  # Note negative values are ok
    return secret


def _get_new_csrf_token():
    return _salt_cipher_secret(_get_new_csrf_string()) </s> remove CSRF_KEY_LENGTH = 32
 </s> add CSRF_SECRET_LENGTH = 32
CSRF_TOKEN_LENGTH = 2 * CSRF_SECRET_LENGTH
CSRF_ALLOWED_CHARS = string.ascii_letters + string.digits
    return _salt_cipher_secret(csrf_secret)
      """
      if "CSRF_COOKIE" not in request.META:
          request.META["CSRF_COOKIE"] = _get_new_csrf_key()
      request.META["CSRF_COOKIE_USED"] = True
    return _salt_cipher_secret(csrf_secret)
  
  
  def rotate_token(request):
      """
      Changes the CSRF token in use for a request - should be done on login
keep keep keep keep replace keep keep keep keep keep
 Fixed #20869 -- made CSRF tokens change every request by salt-encrypting them

Note that the cookie is not changed every request, just the token retrieved
by the `get_token()` method (used also by the `{% csrf_token %}` tag).

While at it, made token validation strict: Where, before, any length was
accepted and non-ASCII chars were ignored, we now treat anything other than
`[A-Za-z0-9]{64}` as invalid (except for 32-char tokens, which, for
backwards-compatibility, are accepted and replaced by 64-char ones).

Thanks Trac user patrys for reporting, github user adambrenecki
for initial patch, Tim Graham for help, and Curtis Maloney,
Collin Anderson, Florian Apolloner, Markus Holtermann & Jon Dufresne
for reviews. 
django/middleware/csrf.py