diff --git a/src/uu/rev/src/rev.rs b/src/uu/rev/src/rev.rs
index db1a907..b06d377 100644
--- a/src/uu/rev/src/rev.rs
+++ b/src/uu/rev/src/rev.rs
@@ -12,11 +12,18 @@ use uucore::{error::UResult, format_usage, help_about, help_usage};
 const ABOUT: &str = help_about!("rev.md");
 const USAGE: &str = help_usage!("rev.md");
 
+mod options {
+    pub const FILE: &str = "file";
+    pub const ZERO: &str = "zero";
+}
+
 #[uucore::main]
 pub fn uumain(args: impl uucore::Args) -> UResult<()> {
     let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
-    let files = matches.get_many::<String>("file");
+    let files = matches.get_many::<String>(options::FILE);
+    let zero = matches.get_flag(options::ZERO);
 
+    let sep = if zero { b'\0' } else { b'\n' };
     match files {
         Some(files) => {
             for path in files {
@@ -25,7 +32,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
                     uucore::show_error!("cannot open {path}: No such file or directory");
                     continue;
                 };
-                if let Err(err) = rev_stream(file) {
+                if let Err(err) = rev_stream(file, sep) {
                     uucore::error::set_exit_code(1);
                     uucore::show_error!("cannot read {path}: {err}");
                 }
@@ -33,28 +40,28 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
         }
         None => {
             let stdin = std::io::stdin().lock();
-            let _ = rev_stream(stdin);
+            let _ = rev_stream(stdin, sep);
         }
     }
 
     Ok(())
 }
 
-fn rev_stream(stream: impl Read) -> std::io::Result<()> {
+fn rev_stream(stream: impl Read, sep: u8) -> std::io::Result<()> {
     let mut stdout = std::io::stdout().lock();
     let mut stream = BufReader::new(stream);
     let mut buf = Vec::with_capacity(4096);
     loop {
         buf.clear();
-        stream.read_until(b'\n', &mut buf)?;
-        if buf.last().copied() != Some(b'\n') {
+        stream.read_until(sep, &mut buf)?;
+        if buf.last().copied() != Some(sep) {
             buf.reverse();
             stdout.write_all(&buf)?;
             break;
         } else {
             buf.pop();
             buf.reverse();
-            buf.push(b'\n');
+            buf.push(sep);
             stdout.write_all(&buf)?;
         }
     }
@@ -68,11 +75,18 @@ pub fn uu_app() -> Command {
         .override_usage(format_usage(USAGE))
         .infer_long_args(true)
         .arg(
-            Arg::new("file")
+            Arg::new(options::FILE)
                 .value_name("FILE")
                 .help("Paths of files to reverse")
                 .index(1)
                 .action(ArgAction::Set)
                 .num_args(1..),
         )
+        .arg(
+            Arg::new(options::ZERO)
+                .short('0')
+                .long("zero")
+                .help("Zero termination. Use the byte '\\0' as line separator.")
+                .action(ArgAction::SetTrue),
+        )
 }
diff --git a/tests/by-util/test_rev.rs b/tests/by-util/test_rev.rs
index b1ad67a..6fe7335 100644
--- a/tests/by-util/test_rev.rs
+++ b/tests/by-util/test_rev.rs
@@ -24,6 +24,18 @@ fn test_existing_file() {
     ucmd.arg("a.txt").succeeds().stdout_is("A enil\nB enil");
 }
 
+#[test]
+fn test_zero() {
+    let (at, mut ucmd) = at_and_ucmd!();
+
+    at.write("a.txt", "line A\0line B");
+
+    ucmd.arg("a.txt")
+        .arg("--zero")
+        .succeeds()
+        .stdout_is("A enil\0B enil");
+}
+
 #[test]
 fn test_multiple_files() {
     let (at, mut ucmd) = at_and_ucmd!();