Index: django/contrib/localflavor/br/forms.py
===================================================================
--- django/contrib/localflavor/br/forms.py	(revision 4940)
+++ django/contrib/localflavor/br/forms.py	(working copy)
@@ -37,3 +37,42 @@
     def __init__(self, attrs=None):
         from br_states import STATE_CHOICES # relative import
         super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
+
+def DV_maker(v):
+    if v >= 2:
+        return 11 - v
+    return 0
+
+class BRCNPJField(Field):
+    def clean(self, value):
+        """ value can be either a string in the format XX.XXX.XXX/XXXX-XX
+        or a group of 14 characters. """
+        value = super(BRCNPJField, self).clean(value)
+        if value in EMPTY_VALUES:
+            return u''
+        orig_value = value[:]
+        if not value.isdigit():
+            value = re.sub("[-/\.]", "", value)
+        try:
+            int(value)
+        except ValueError:
+            raise ValidationError(u"This field requires only numbers")
+        if len(value) != 14:
+            raise ValidationError(
+                gettext(u"This field requires at least 14 digits"))
+        orig_dv = value[-2:]
+
+        new_1dv = sum([i * int(value[idx])
+                         for idx, i in enumerate(range(5, 1, -1) +
+                                                 range(9, 1, -1))])
+        new_1dv = DV_maker(new_1dv % 11)
+        value = value[:-2] + str(new_1dv) + value[-1]
+        new_2dv = sum([i * int(value[idx])
+                         for idx, i in enumerate(range(6, 1, -1) +
+                                                 range(9, 1, -1))])
+        new_2dv = DV_maker(new_2dv % 11)
+        value = value[:-1] + str(new_2dv)
+        if (value[-2:] != orig_dv):
+            raise ValidationError(gettext(u"Invalid CNPJ number"))
+
+        return orig_value
Index: tests/regressiontests/forms/localflavor.py
===================================================================
--- tests/regressiontests/forms/localflavor.py	(revision 4940)
+++ tests/regressiontests/forms/localflavor.py	(working copy)
@@ -800,6 +800,40 @@
 >>> f.clean('12345-123')
 u'12345-123'
 
+# BRCNPJField ############################################################
+
+>>> from django.contrib.localflavor.br.forms import BRCNPJField
+>>> f = BRCNPJField(required=True)
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('12-345-678/9012-10')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CNPJ number']
+>>> f.clean('12.345.678/9012-10')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CNPJ number']
+>>> f.clean('12345678/9012-10')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CNPJ number']
+>>> f.clean('64.132.916/0001-88')
+'64.132.916/0001-88'
+>>> f.clean('64-132-916/0001-88')
+'64-132-916/0001-88'
+>>> f.clean('64132916/0001-88')
+'64132916/0001-88'
+>>> f.clean('64.132.916/0001-XX')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires only numbers']
+>>> f = BRCNPJField(required=False)
+>>> f.clean('')
+u''
+
 # BRPhoneNumberField #########################################################
 
 >>> from django.contrib.localflavor.br.forms import BRPhoneNumberField
