diff --git a/src/croniter/croniter.py b/src/croniter/croniter.py
index 2a3e3c8..9124954 100644
--- a/src/croniter/croniter.py
+++ b/src/croniter/croniter.py
@@ -787,7 +787,12 @@ class croniter(object):
             res = set(res)
             res = sorted(res, key=lambda i: "{:02}".format(i) if isinstance(i, int) else i)
             if len(res) == cls.LEN_MEANS_ALL[i]:
-                res = ['*']
+                # Make sure the wildcard is used in the correct way (avoid over-optimization)
+                if ((i == 2 and '*' not in expressions[4]) or
+                    (i == 4 and '*' not in expressions[2])):
+                    pass
+                else:
+                    res = ['*']
 
             expanded.append(['*'] if (len(res) == 1
                                       and res[0] == '*')
@@ -798,7 +803,8 @@ class croniter(object):
             dow_expanded_set = set(expanded[4])
             dow_expanded_set = dow_expanded_set.difference(nth_weekday_of_month.keys())
             dow_expanded_set.discard("*")
-            if dow_expanded_set:
+            # Skip: if it's all weeks instead of wildcard
+            if dow_expanded_set and len(set(expanded[4])) != cls.LEN_MEANS_ALL[4]:
                 raise CroniterUnsupportedSyntaxError(
                     "day-of-week field does not support mixing literal values and nth day of week syntax.  "
                     "Cron: '{}'    dow={} vs nth={}".format(expr_format, dow_expanded_set, nth_weekday_of_month))
@@ -824,6 +830,11 @@ class croniter(object):
 
     @classmethod
     def is_valid(cls, expression, hash_id=None):
+        if hash_id:
+            if not isinstance(hash_id, (bytes, str)):
+                raise TypeError('hash_id must be bytes or UTF-8 string')
+            if not isinstance(hash_id, bytes):
+                hash_id = hash_id.encode('UTF-8')
         try:
             cls.expand(expression, hash_id=hash_id)
         except CroniterError:

diff --git a/src/croniter/tests/test_croniter.py b/src/croniter/tests/test_croniter.py
index 1dcfb0b..b2ea829 100755
--- a/src/croniter/tests/test_croniter.py
+++ b/src/croniter/tests/test_croniter.py
@@ -344,11 +344,15 @@ class CroniterTest(base.TestCase):
         # Test each field individually
         self.assertEqual(croniter('0-59 0 1 1 0').expanded[m], wildcard)
         self.assertEqual(croniter('0 0-23 1 1 0').expanded[h], wildcard)
-        self.assertEqual(croniter('0 0 1-31 1 0').expanded[d], wildcard)
+        self.assertNotEqual(croniter('0 0 1-31 1 0').expanded[d], wildcard)
+        self.assertEqual(croniter('0 0 1-31 1 *').expanded[d], wildcard)
         self.assertEqual(croniter('0 0 1 1-12 0').expanded[mon], wildcard)
-        self.assertEqual(croniter('0 0 1 1 0-6').expanded[dow], wildcard)
-        self.assertEqual(croniter('0 0 1 1 1-7').expanded[dow], wildcard)
-        self.assertEqual(croniter('0 0 1 1 1-7,sat#3').expanded[dow], wildcard)
+        self.assertNotEqual(croniter('0 0 1 1 0-6').expanded[dow], wildcard)
+        self.assertEqual(croniter('0 0 * 1 0-6').expanded[dow], wildcard)
+        self.assertNotEqual(croniter('0 0 1 1 1-7').expanded[dow], wildcard)
+        self.assertEqual(croniter('0 0 * 1 1-7').expanded[dow], wildcard)
+        self.assertNotEqual(croniter('0 0 1 1 1-7,sat#3').expanded[dow], wildcard)
+        self.assertEqual(croniter('0 0 * 1 1-7,sat#3').expanded[dow], wildcard)
         self.assertEqual(croniter('0 0 1 1 0 0-59').expanded[s], wildcard)
         # Real life examples
         self.assertEqual(croniter('30 1-12,0,10-23 15-21 * fri').expanded[h], wildcard)

Croniter expression "* * 5 3 1-7" does not match weeks
I want to match March 5th or Monday to Sunday in March, so I used the expression `* * 5 3 1-7`, but the expression optimization will convert the expression to `* * 5 3 *`, so that only Match March 5th. Let's look at another example, `* * 5 3 1-6` is correct, the expression will be converted to `* * 5 3 1,2,3,4,5,6`, so it will not only match March 5 , it can also match every day in March except Sunday.
src/croniter/tests/test_croniter.py::CroniterTest::testOptimizeCronExpressions
src/croniter/tests/test_croniter.py::CroniterTest::testBlockDupRanges src/croniter/tests/test_croniter.py::CroniterTest::testBug1 src/croniter/tests/test_croniter.py::CroniterTest::testBug2 src/croniter/tests/test_croniter.py::CroniterTest::testBug3 src/croniter/tests/test_croniter.py::CroniterTest::testBug57 src/croniter/tests/test_croniter.py::CroniterTest::testDay src/croniter/tests/test_croniter.py::CroniterTest::testDay2 src/croniter/tests/test_croniter.py::CroniterTest::testDomDowVixieCronBug src/croniter/tests/test_croniter.py::CroniterTest::testError src/croniter/tests/test_croniter.py::CroniterTest::testGetCurrent src/croniter/tests/test_croniter.py::CroniterTest::testHour src/croniter/tests/test_croniter.py::CroniterTest::testISOWeekday src/croniter/tests/test_croniter.py::CroniterTest::testInitNoStartTime src/croniter/tests/test_croniter.py::CroniterTest::testLastDayOfMonth src/croniter/tests/test_croniter.py::CroniterTest::testMinute src/croniter/tests/test_croniter.py::CroniterTest::testMonth src/croniter/tests/test_croniter.py::CroniterTest::testNthWeekDay src/croniter/tests/test_croniter.py::CroniterTest::testPrevDayOfMonthWithCrossing src/croniter/tests/test_croniter.py::CroniterTest::testPrevLastDayOfMonth src/croniter/tests/test_croniter.py::CroniterTest::testPrevMinute src/croniter/tests/test_croniter.py::CroniterTest::testPrevNthWeekDay src/croniter/tests/test_croniter.py::CroniterTest::testPrevWeekDay src/croniter/tests/test_croniter.py::CroniterTest::testPrevWeekDay2 src/croniter/tests/test_croniter.py::CroniterTest::testPreviousDay src/croniter/tests/test_croniter.py::CroniterTest::testPreviousDow src/croniter/tests/test_croniter.py::CroniterTest::testPreviousHour src/croniter/tests/test_croniter.py::CroniterTest::testPreviousMonth src/croniter/tests/test_croniter.py::CroniterTest::testRangeWithUppercaseLastDayOfMonth src/croniter/tests/test_croniter.py::CroniterTest::testSecond src/croniter/tests/test_croniter.py::CroniterTest::testSecondRepeat src/croniter/tests/test_croniter.py::CroniterTest::testSecondSec src/croniter/tests/test_croniter.py::CroniterTest::testSundayToThursdayWithAlphaConversion src/croniter/tests/test_croniter.py::CroniterTest::testTimezone src/croniter/tests/test_croniter.py::CroniterTest::testTimezoneDateutil src/croniter/tests/test_croniter.py::CroniterTest::testTimezoneSummerTime src/croniter/tests/test_croniter.py::CroniterTest::testTimezoneWinterTime src/croniter/tests/test_croniter.py::CroniterTest::testWeekDay src/croniter/tests/test_croniter.py::CroniterTest::testWeekDayDayAnd src/croniter/tests/test_croniter.py::CroniterTest::test_bug34 src/croniter/tests/test_croniter.py::CroniterTest::test_bug_62_leap src/croniter/tests/test_croniter.py::CroniterTest::test_confirm_sort src/croniter/tests/test_croniter.py::CroniterTest::test_dst_issue90_st31ny src/croniter/tests/test_croniter.py::CroniterTest::test_dst_iter src/croniter/tests/test_croniter.py::CroniterTest::test_error_alpha_cron src/croniter/tests/test_croniter.py::CroniterTest::test_error_bad_cron src/croniter/tests/test_croniter.py::CroniterTest::test_exactly_the_same_minute src/croniter/tests/test_croniter.py::CroniterTest::test_explicit_year_forward src/croniter/tests/test_croniter.py::CroniterTest::test_hash_mixup_all_fri_3rd_sat src/croniter/tests/test_croniter.py::CroniterTest::test_invalid_zerorepeat src/croniter/tests/test_croniter.py::CroniterTest::test_is_valid src/croniter/tests/test_croniter.py::CroniterTest::test_issue145_getnext src/croniter/tests/test_croniter.py::CroniterTest::test_issue151 src/croniter/tests/test_croniter.py::CroniterTest::test_issue156 src/croniter/tests/test_croniter.py::CroniterTest::test_issue_142_dow src/croniter/tests/test_croniter.py::CroniterTest::test_issue_47 src/croniter/tests/test_croniter.py::CroniterTest::test_issue_k11 src/croniter/tests/test_croniter.py::CroniterTest::test_issue_k12 src/croniter/tests/test_croniter.py::CroniterTest::test_issue_k33 src/croniter/tests/test_croniter.py::CroniterTest::test_issue_k34 src/croniter/tests/test_croniter.py::CroniterTest::test_issue_k6 src/croniter/tests/test_croniter.py::CroniterTest::test_issue_monsun_117 src/croniter/tests/test_croniter.py::CroniterTest::test_last_out_of_range src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_friday src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_friday_2hours src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_friday_2xh_2xm src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_mixup_4th_and_last src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_mixup_all_fri_last_sat src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_mixup_firstlast_sat src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_saturday_rev src/croniter/tests/test_croniter.py::CroniterTest::test_lwom_tue_thu src/croniter/tests/test_croniter.py::CroniterTest::test_match src/croniter/tests/test_croniter.py::CroniterTest::test_match_range src/croniter/tests/test_croniter.py::CroniterTest::test_milliseconds src/croniter/tests/test_croniter.py::CroniterTest::test_mixdow src/croniter/tests/test_croniter.py::CroniterTest::test_multiple_months src/croniter/tests/test_croniter.py::CroniterTest::test_next_when_now_satisfies_cron src/croniter/tests/test_croniter.py::CroniterTest::test_nth_as_last_wday_simple src/croniter/tests/test_croniter.py::CroniterTest::test_nth_out_of_range src/croniter/tests/test_croniter.py::CroniterTest::test_nth_wday_simple src/croniter/tests/test_croniter.py::CroniterTest::test_overflow src/croniter/tests/test_croniter.py::CroniterTest::test_rangeGenerator src/croniter/tests/test_croniter.py::CroniterTest::test_std_dst src/croniter/tests/test_croniter.py::CroniterTest::test_std_dst2 src/croniter/tests/test_croniter.py::CroniterTest::test_std_dst3 src/croniter/tests/test_croniter.py::CroniterTest::test_wdom_core_leap_year src/croniter/tests/test_croniter.py::CroniterTest::test_weekday_range