diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs
index 36dfbbe1e3d..c5c362c5936 100644
--- a/src/uu/cksum/src/cksum.rs
+++ b/src/uu/cksum/src/cksum.rs
@@ -15,6 +15,7 @@ use std::io::{self, stdin, stdout, BufReader, Read, Write};
 use std::iter;
 use std::path::Path;
 use uucore::{
+    encoding,
     error::{FromIo, UError, UResult, USimpleError},
     format_usage, help_about, help_section, help_usage, show,
     sum::{
@@ -44,6 +45,13 @@ enum CkSumError {
     RawMultipleFiles,
 }
 
+#[derive(Debug, PartialEq)]
+enum OutputFormat {
+    Hexadecimal,
+    Raw,
+    Base64,
+}
+
 impl UError for CkSumError {
     fn code(&self) -> i32 {
         match self {
@@ -138,7 +146,7 @@ struct Options {
     output_bits: usize,
     untagged: bool,
     length: Option<usize>,
-    raw: bool,
+    output_format: OutputFormat,
 }
 
 /// Calculate checksum
@@ -153,7 +161,7 @@ where
     I: Iterator<Item = &'a OsStr>,
 {
     let files: Vec<_> = files.collect();
-    if options.raw && files.len() > 1 {
+    if options.output_format == OutputFormat::Raw && files.len() > 1 {
         return Err(Box::new(CkSumError::RawMultipleFiles));
     }
 
@@ -177,7 +185,7 @@ where
             };
             Box::new(file_buf) as Box<dyn Read>
         });
-        let (sum, sz) = digest_read(&mut options.digest, &mut file, options.output_bits)
+        let (sum_hex, sz) = digest_read(&mut options.digest, &mut file, options.output_bits)
             .map_err_context(|| "failed to read input".to_string())?;
         if filename.is_dir() {
             show!(USimpleError::new(
@@ -186,17 +194,25 @@ where
             ));
             continue;
         }
-        if options.raw {
-            let bytes = match options.algo_name {
-                ALGORITHM_OPTIONS_CRC => sum.parse::<u32>().unwrap().to_be_bytes().to_vec(),
-                ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => {
-                    sum.parse::<u16>().unwrap().to_be_bytes().to_vec()
-                }
-                _ => decode(sum).unwrap(),
-            };
-            stdout().write_all(&bytes)?;
-            return Ok(());
-        }
+        let sum = match options.output_format {
+            OutputFormat::Raw => {
+                let bytes = match options.algo_name {
+                    ALGORITHM_OPTIONS_CRC => sum_hex.parse::<u32>().unwrap().to_be_bytes().to_vec(),
+                    ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => {
+                        sum_hex.parse::<u16>().unwrap().to_be_bytes().to_vec()
+                    }
+                    _ => decode(sum_hex).unwrap(),
+                };
+                // Cannot handle multiple files anyway, output immediately.
+                stdout().write_all(&bytes)?;
+                return Ok(());
+            }
+            OutputFormat::Hexadecimal => sum_hex,
+            OutputFormat::Base64 => match options.algo_name {
+                ALGORITHM_OPTIONS_CRC | ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => sum_hex,
+                _ => encoding::encode(encoding::Format::Base64, &decode(sum_hex).unwrap()).unwrap(),
+            },
+        };
         // The BSD checksum output is 5 digit integer
         let bsd_width = 5;
         match (options.algo_name, not_file) {
@@ -286,8 +302,10 @@ mod options {
     pub const ALGORITHM: &str = "algorithm";
     pub const FILE: &str = "file";
     pub const UNTAGGED: &str = "untagged";
+    pub const TAG: &str = "tag";
     pub const LENGTH: &str = "length";
     pub const RAW: &str = "raw";
+    pub const BASE64: &str = "base64";
 }
 
 #[uucore::main]
@@ -342,13 +360,21 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
 
     let (name, algo, bits) = detect_algo(algo_name, length);
 
+    let output_format = if matches.get_flag(options::RAW) {
+        OutputFormat::Raw
+    } else if matches.get_flag(options::BASE64) {
+        OutputFormat::Base64
+    } else {
+        OutputFormat::Hexadecimal
+    };
+
     let opts = Options {
         algo_name: name,
         digest: algo,
         output_bits: bits,
         length,
         untagged: matches.get_flag(options::UNTAGGED),
-        raw: matches.get_flag(options::RAW),
+        output_format,
     };
 
     match matches.get_many::<String>(options::FILE) {
@@ -365,6 +391,7 @@ pub fn uu_app() -> Command {
         .about(ABOUT)
         .override_usage(format_usage(USAGE))
         .infer_long_args(true)
+        .args_override_self(true)
         .arg(
             Arg::new(options::FILE)
                 .hide(true)
@@ -395,6 +422,13 @@ pub fn uu_app() -> Command {
             Arg::new(options::UNTAGGED)
                 .long(options::UNTAGGED)
                 .help("create a reversed style checksum, without digest type")
+                .action(ArgAction::SetTrue)
+                .overrides_with(options::TAG),
+        )
+        .arg(
+            Arg::new(options::TAG)
+                .long(options::TAG)
+                .help("create a BSD style checksum, undo --untagged (default)")
                 .action(ArgAction::SetTrue),
         )
         .arg(
@@ -411,5 +445,14 @@ pub fn uu_app() -> Command {
             .help("emit a raw binary digest, not hexadecimal")
             .action(ArgAction::SetTrue),
         )
+        .arg(
+            Arg::new(options::BASE64)
+            .long(options::BASE64)
+            .help("emit a base64 digest, not hexadecimal")
+            .action(ArgAction::SetTrue)
+            // Even though this could easily just override an earlier '--raw',
+            // GNU cksum does not permit these flags to be combined:
+            .conflicts_with(options::RAW),
+        )
         .after_help(AFTER_HELP)
 }
diff --git a/src/uucore/src/lib/features/encoding.rs b/src/uucore/src/lib/features/encoding.rs
index 0ed54839dc0..dd89c1f5201 100644
--- a/src/uucore/src/lib/features/encoding.rs
+++ b/src/uucore/src/lib/features/encoding.rs
@@ -23,6 +23,7 @@ pub enum DecodeError {
     Io(#[from] io::Error),
 }
 
+#[derive(Debug)]
 pub enum EncodeError {
     Z85InputLenNotMultipleOf4,
     InvalidInput,
diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs
index 464de947479..12c54d610a1 100644
--- a/tests/by-util/test_cksum.rs
+++ b/tests/by-util/test_cksum.rs
@@ -128,6 +128,29 @@ fn test_stdin_larger_than_128_bytes() {
     assert_eq!(bytes_cnt, 2058);
 }
 
+#[test]
+fn test_repeated_flags() {
+    new_ucmd!()
+        .arg("-a")
+        .arg("sha1")
+        .arg("--algo=sha256")
+        .arg("-a=md5")
+        .arg("lorem_ipsum.txt")
+        .succeeds()
+        .stdout_is_fixture("md5_single_file.expected");
+}
+
+#[test]
+fn test_tag_after_untagged() {
+    new_ucmd!()
+        .arg("--untagged")
+        .arg("--tag")
+        .arg("-a=md5")
+        .arg("lorem_ipsum.txt")
+        .succeeds()
+        .stdout_is_fixture("md5_single_file.expected");
+}
+
 #[test]
 fn test_algorithm_single_file() {
     for algo in ALGOS {
@@ -208,6 +231,17 @@ fn test_untagged_algorithm_single_file() {
     }
 }
 
+#[test]
+fn test_untagged_algorithm_after_tag() {
+    new_ucmd!()
+        .arg("--tag")
+        .arg("--untagged")
+        .arg("--algorithm=md5")
+        .arg("lorem_ipsum.txt")
+        .succeeds()
+        .stdout_is_fixture("untagged/md5_single_file.expected");
+}
+
 #[test]
 fn test_untagged_algorithm_multiple_files() {
     for algo in ALGOS {
@@ -291,6 +325,20 @@ fn test_length_is_zero() {
         .stdout_is_fixture("length_is_zero.expected");
 }
 
+#[test]
+fn test_length_repeated() {
+    new_ucmd!()
+        .arg("--length=10")
+        .arg("--length=123456")
+        .arg("--length=0")
+        .arg("--algorithm=blake2b")
+        .arg("lorem_ipsum.txt")
+        .arg("alice_in_wonderland.txt")
+        .succeeds()
+        .no_stderr()
+        .stdout_is_fixture("length_is_zero.expected");
+}
+
 #[test]
 fn test_raw_single_file() {
     for algo in ALGOS {
@@ -315,6 +363,43 @@ fn test_raw_multiple_files() {
         .code_is(1);
 }
 
+#[test]
+fn test_base64_raw_conflicts() {
+    new_ucmd!()
+        .arg("--base64")
+        .arg("--raw")
+        .arg("lorem_ipsum.txt")
+        .fails()
+        .no_stdout()
+        .stderr_contains("--base64")
+        .stderr_contains("cannot be used with")
+        .stderr_contains("--raw");
+}
+
+#[test]
+fn test_base64_single_file() {
+    for algo in ALGOS {
+        new_ucmd!()
+            .arg("--base64")
+            .arg("lorem_ipsum.txt")
+            .arg(format!("--algorithm={algo}"))
+            .succeeds()
+            .no_stderr()
+            .stdout_is_fixture_bytes(format!("base64/{algo}_single_file.expected"));
+    }
+}
+#[test]
+fn test_base64_multiple_files() {
+    new_ucmd!()
+        .arg("--base64")
+        .arg("--algorithm=md5")
+        .arg("lorem_ipsum.txt")
+        .arg("alice_in_wonderland.txt")
+        .succeeds()
+        .no_stderr()
+        .stdout_is_fixture_bytes(format!("base64/md5_multiple_files.expected"));
+}
+
 #[test]
 fn test_fail_on_folder() {
     let (at, mut ucmd) = at_and_ucmd!();
diff --git a/tests/fixtures/cksum/base64/blake2b_single_file.expected b/tests/fixtures/cksum/base64/blake2b_single_file.expected
new file mode 100644
index 00000000000..18bec38f017
--- /dev/null
+++ b/tests/fixtures/cksum/base64/blake2b_single_file.expected
@@ -0,0 +1 @@
+BLAKE2b (lorem_ipsum.txt) = DpegkYnlYMN4nAv/HwIBZoYe+FfR+/5FdN4YQuPAbKu5V15K9jCaFmFYwrQI08A4wbSdgos1FYFCzcA5bRGVww==
diff --git a/tests/fixtures/cksum/base64/bsd_single_file.expected b/tests/fixtures/cksum/base64/bsd_single_file.expected
new file mode 100644
index 00000000000..293ada3bd61
--- /dev/null
+++ b/tests/fixtures/cksum/base64/bsd_single_file.expected
@@ -0,0 +1 @@
+08109     1 lorem_ipsum.txt
diff --git a/tests/fixtures/cksum/base64/crc_single_file.expected b/tests/fixtures/cksum/base64/crc_single_file.expected
new file mode 100644
index 00000000000..e9fc1ca7cf4
--- /dev/null
+++ b/tests/fixtures/cksum/base64/crc_single_file.expected
@@ -0,0 +1 @@
+378294376 772 lorem_ipsum.txt
diff --git a/tests/fixtures/cksum/base64/md5_multiple_files.expected b/tests/fixtures/cksum/base64/md5_multiple_files.expected
new file mode 100644
index 00000000000..e7f844b9ac7
--- /dev/null
+++ b/tests/fixtures/cksum/base64/md5_multiple_files.expected
@@ -0,0 +1,2 @@
+MD5 (lorem_ipsum.txt) = zXJGkPfcYXdd+sQApx8sqg==
+MD5 (alice_in_wonderland.txt) = 9vpwM+FhZqlYmqHAOI/9WA==
diff --git a/tests/fixtures/cksum/base64/md5_single_file.expected b/tests/fixtures/cksum/base64/md5_single_file.expected
new file mode 100644
index 00000000000..8a12f79278c
--- /dev/null
+++ b/tests/fixtures/cksum/base64/md5_single_file.expected
@@ -0,0 +1 @@
+MD5 (lorem_ipsum.txt) = zXJGkPfcYXdd+sQApx8sqg==
diff --git a/tests/fixtures/cksum/base64/sha1_single_file.expected b/tests/fixtures/cksum/base64/sha1_single_file.expected
new file mode 100644
index 00000000000..b12608e77c7
--- /dev/null
+++ b/tests/fixtures/cksum/base64/sha1_single_file.expected
@@ -0,0 +1 @@
+SHA1 (lorem_ipsum.txt) = qx3QuuHYiDo9GKZt5q+9KCUs++8=
diff --git a/tests/fixtures/cksum/base64/sha224_single_file.expected b/tests/fixtures/cksum/base64/sha224_single_file.expected
new file mode 100644
index 00000000000..69d85abdb86
--- /dev/null
+++ b/tests/fixtures/cksum/base64/sha224_single_file.expected
@@ -0,0 +1 @@
+SHA224 (lorem_ipsum.txt) = PeZvvK0QbhtAqzkb5WxR0gB+sfnGVdD04pv8AQ==
diff --git a/tests/fixtures/cksum/base64/sha256_single_file.expected b/tests/fixtures/cksum/base64/sha256_single_file.expected
new file mode 100644
index 00000000000..d9a8814a30b
--- /dev/null
+++ b/tests/fixtures/cksum/base64/sha256_single_file.expected
@@ -0,0 +1 @@
+SHA256 (lorem_ipsum.txt) = 98QgUBxQ4AswklAQDWfqXpEJgVNrRYL+nENb2Ss/HwI=
diff --git a/tests/fixtures/cksum/base64/sha384_single_file.expected b/tests/fixtures/cksum/base64/sha384_single_file.expected
new file mode 100644
index 00000000000..8a8333d3553
--- /dev/null
+++ b/tests/fixtures/cksum/base64/sha384_single_file.expected
@@ -0,0 +1 @@
+SHA384 (lorem_ipsum.txt) = S+S5Cg0NMpZpkpIQGfJKvIJNz7ixxAgQLx9niPuAupqaTFp7V1ozU6kKjucZSB3L
diff --git a/tests/fixtures/cksum/base64/sha512_single_file.expected b/tests/fixtures/cksum/base64/sha512_single_file.expected
new file mode 100644
index 00000000000..da36c4295fb
--- /dev/null
+++ b/tests/fixtures/cksum/base64/sha512_single_file.expected
@@ -0,0 +1 @@
+SHA512 (lorem_ipsum.txt) = llRkqyVWqtWOvHPYmtIh5Vl5dSnsr8D0ZsEXlc/21uLGD5agfFQs/R9Cbl5P4KSKoVZnukQJayE9CBPNA436BQ==
diff --git a/tests/fixtures/cksum/base64/sm3_single_file.expected b/tests/fixtures/cksum/base64/sm3_single_file.expected
new file mode 100644
index 00000000000..e4ca582c938
--- /dev/null
+++ b/tests/fixtures/cksum/base64/sm3_single_file.expected
@@ -0,0 +1 @@
+SM3 (lorem_ipsum.txt) = bSlrgF0GC/7SKAjfMI27m0MXeU3U7WdAoQdwp4Jpm8I=
diff --git a/tests/fixtures/cksum/base64/sysv_single_file.expected b/tests/fixtures/cksum/base64/sysv_single_file.expected
new file mode 100644
index 00000000000..e0f7252cbe8
--- /dev/null
+++ b/tests/fixtures/cksum/base64/sysv_single_file.expected
@@ -0,0 +1 @@
+6985 2 lorem_ipsum.txt