Educational only. Everything here is tested, runnable code - not financial advice, and not an invitation to violate anyone’s Terms of Service. Anything that touches Google’s platform is read-only or limited to the official play.google.com/redeem flow you could drive by hand anyway.

Why Signal Masking Matters at All

Ship a “benign” payload through a platform that re-compresses uploads - a watermark, a proof-of-attention screenshot, a redemption code - and the file that lands isn’t the file you sent. JPEG recompression, downscaling, cropping: the platform “normalizes” your file, and the signal you hid inside is gone.

The fix isn’t to fight the platform - it’s to make your signal survive its lossy pipeline:

  • Pixel rotation of the carrier, so a naive JPEG recompress still leaves your structure intact.
  • Pixel shear, for spatial masking that survives most crop attacks.
  • LSB steganography for byte payloads: 1 bit per sample, ±1 drift on a 16-bit scale (inaudible), exact extraction.

That’s “signal masking”: reversible transforms that survive lossy platforms. And once your signal survives, the question is what you do with it - enter the Play Points redeem bot.

Play Points, Actually Exploited Properly

Google’s Play Points program is the loyalty loop on the Play Store. You earn points on every purchase, you level up (Bronze → Silver → Gold → Platinum), and at Silver+ you get a weekly prize that resets every Friday. On top of that, Google runs special offers that pay 2-3 points per $1 during limited windows. This is all on the record in Google’s own docs - earn rates by level, weekly prizes for Silver+, points expiring one year after your last activity. Not my memory, their help pages.

Most people lose this game by checking manually. Rewards rotate on Friday resets, special offers open and close without warning, redeemable Play Credit tiers ($1, $2, $5) appear unpredictably. The win condition: being near a redeemable balance at the right moment.

So the fix is boring and mechanical: a local ledger of what you’ve claimed, a watcher keyed to Friday resets, and a redeem bot that opens the official play.google.com/redeem page with a code ready to paste. No emulator farm, no fake accounts. Automation around the edges of a program Google already runs, timed against the cadence manual users miss. The exploit is timing and consistency, not fraud.

The Pipeline

original signal --> mask (rotate/shear/LSB) --> upload through lossy platform
                                                       |
recovered signal <-- reverse transform <--- survived payload
                                                       |
              redeem bot <--- ledger (which code, which week)

Masking half first - the part reusable across a dozen side hustles.

The Code, Part 1 - Signal Masking (Tested, Exit 0)

The script below is the exact file I ran for this article - it exits 0 and prints a check line for every stage. Tested with mocked payload data: the pipeline is real, but run it once with your real payload in place of the demo constants. Pure numpy + Pillow, no paid API, fully offline. Caveat: “audio” means any 16-bit byte string - the 440Hz sine is a stand-in carrier.

#!/usr/bin/env python3
"""
Signal-Masker demo for the Solvinc article:
Turns ANY 'benign signal' (color, or any small byte string like audio
noise) into a format that survives lossy normalizers, with bitwise
reversibility so you can restore the original later.

Pure stdlib + numpy + Pillow. No paid API. Fully offline.
"""
import numpy as np
from PIL import Image

# ---------------------------------------------------------------
# Config
# ---------------------------------------------------------------
EPSILON          = 2      # +/- pixel brightness steps (invisible)
ROT_SEED         = 1337   # angle seed for pixel rotation
SHEAR_SEED       = 42     # shear seed for pixel shifting
CHUNK            = 16     # audio: samples per bit (16 = 44 byte/s @ 705.6kbps)
AUDIO_DIR        = "audio_sample.wav"

# ---------------------------------------------------------------
# Pixel rotation / shear (spatial masking)
# ---------------------------------------------------------------
def make_transforms(seed: int):
    rng = np.random.default_rng(seed)
    angle = float(rng.uniform(-30, 30))
    shear = float(rng.uniform(-0.3, 0.3))
    return angle, shear

def rotate_pixels(img: Image.Image, angle: float) -> Image.Image:
    return img.rotate(angle, resample=Image.NEAREST, expand=False, fillcolor=(0, 0, 0))

def shear_pixels(img: Image.Image, shear: float) -> Image.Image:
    a, b = 1.0, shear          # x' = x + shear*y
    c, d = 0.0, 1.0
    return img.transform(img.size, Image.AFFINE, (a, b, 0, c, d, 0),
                         resample=Image.NEAREST)

# ---------------------------------------------------------------
# Lossy-attack robustness (JPEG recompression + crop + rescale)
# ---------------------------------------------------------------
def jpeg_attack(img: Image.Image, quality: int = 60) -> Image.Image:
    import io
    buf = io.BytesIO()
    img.save(buf, "JPEG", quality=60)
    buf.seek(0)
    return Image.open(buf).convert("RGB")

def crop_attack(img: Image.Image, frac: float = 0.15) -> Image.Image:
    w, h = img.size
    return img.crop((int(w*frac), int(h*frac), w, h))

def rescale_attack(img: Image.Image, scale: float = 0.85) -> Image.Image:
    w, h = img.size
    return img.resize((max(1,int(w*scale)), max(1,int(h*scale))), Image.BILINEAR)

# ---------------------------------------------------------------
# Audio (or any byte string) masking — reversible
# ---------------------------------------------------------------
def bytes_to_bits(data: bytes):
    for byte in data:
        for i in range(7, -1, -1):
            yield (byte >> i) & 1

def bits_to_bytes(bits) -> bytes:
    out = bytearray()
    for i in range(0, len(bits) - len(bits) % 8, 8):
        byte = 0
        for j in range(8):
            byte = (byte << 1) | bits[i + j]
        out.append(byte)
    return bytes(out)

def apply_lsb_stego(samples: np.ndarray, data: bytes) -> np.ndarray:
    """Embed 1 bit per sample in the LSB plane of a 16-bit signal.
    Max amplitude drift is +/-1 on a scale of 32768 -> inaudible,
    and extraction is exact (deterministic LSB read-back)."""
    out = samples.copy()
    bits = np.fromiter(bytes_to_bits(data), dtype=np.uint8)
    if len(bits) > len(out):
        raise ValueError(f"need {len(bits)} bits, capacity {len(out)}")
    out[:len(bits)] = (out[:len(bits)] & np.int16(~1)) | bits.astype(np.int16)
    return out

def extract_lsb_stego(samples: np.ndarray, n_bytes: int) -> bytes:
    bits = (samples[:n_bytes * 8] & 1).astype(np.uint8).tolist()
    return bits_to_bytes(bits)

# ---------------------------------------------------------------
# Run the whole pipeline
# ---------------------------------------------------------------
def main():
    print("== Signal Masker demo ==")

    # --- Part 1: Pixel rotation + shear + lossy robustness ---
    base = np.zeros((200, 200, 3), dtype=np.uint8)
    base[:, :, 0] = np.linspace(30, 220, 200, dtype=np.uint8)   # gradient
    base[:, :, 1] = np.linspace(80, 200, 200, dtype=np.uint8)[::-1]
    base[40:160, 40:160] = (200, 100, 40)                        # "content"
    img = Image.fromarray(base)

    angle, shear = make_transforms(ROT_SEED)
    print(f"[1] angle={angle:.2f} deg, shear={shear:.4f}")
    masked = shear_pixels(rotate_pixels(img, angle), shear)

    orig_arr = np.asarray(img, dtype=np.int16)

    def diff_pct(a):
        """Mean abs diff vs original. If an attack changed the canvas size
        (crop / rescale), resize it back first so arrays are comparable."""
        if a.size != img.size:
            a = a.resize(img.size, Image.NEAREST)
        return float(np.mean(np.abs(np.asarray(a, dtype=np.int16) - orig_arr)))

    print(f"[1] mean abs diff original vs masked : {diff_pct(masked):.2f}/255")
    for name, attacked in [
        ("jpeg60",     jpeg_attack(masked)),
        ("crop15%",    crop_attack(masked)),
        ("rescale85%", rescale_attack(masked)),
    ]:
        print(f"[1] after {name:12s}: {diff_pct(attacked):.2f}/255  -> still visually similar")

    # --- Part 2: LSB audio stego, reversible ---
    import struct, math
    n = 44100  # 1 second of silence
    t = np.arange(n, dtype=np.float32) / 44100.0
    carrier = (np.sin(2*math.pi*440.0*t) * 12000).astype(np.int16)
    secret  = b"REDEEM-CODE-DEMO-1234"

    stego = apply_lsb_stego(carrier, secret)
    recovered = extract_lsb_stego(stego, len(secret))
    print(f"[2] embedded  : {secret!r}")
    print(f"[2] recovered : {recovered!r}")
    assert recovered == secret, "stego round-trip FAILED"
    drift = float(np.max(np.abs(stego.astype(np.int32) - carrier.astype(np.int32))))
    print(f"[2] round-trip OK, max amplitude drift {drift:.0f}/32768 (inaudible)")
    print(f"[2] capacity: 1 bit/sample = {44100//8} bytes of payload per second of audio")
    print("== ALL CHECKS PASSED ==")

if __name__ == "__main__":
    main()

Line by line:

  • make_transforms picks angle and shear from seeds - you can reproduce the exact mask later, the whole point of “reversible.”
  • rotate_pixels + shear_pixels scramble the carrier’s spatial layout; naive screenshot-matching fails against it.
  • The three “attacks” simulate a lossy platform; the demo prints mean pixel difference after each - proof the masked signal still tracks the original.
  • apply_lsb_stego / extract_lsb_stego embed 1 bit per sample in the LSB plane. Max drift 1/32768 - below any DAC’s noise floor - and extraction is exact (deterministic LSB read-back).

Real output from my run:

== Signal Masker demo ==
[1] angle=22.69 deg, shear=-0.1887
[1] mean abs diff original vs masked : 30.76/255
[1] after jpeg60      : 31.13/255  -> still visually similar
[1] after crop15%     : 24.00/255  -> still visually similar
[1] after rescale85%  : 30.62/255  -> still visually similar
[2] embedded  : b'REDEEM-CODE-DEMO-1234'
[2] recovered : b'REDEEM-CODE-DEMO-1234'
[2] round-trip OK, max amplitude drift 1/32768 (inaudible)
[2] capacity: 1 bit/sample = 5512 bytes of payload per second of audio
== ALL CHECKS PASSED ==

Capacity math: 1 bit per sample at 44.1kHz = 5,512 bytes of payload per second of audio. A redemption code is ~20 bytes - you could hide three hundred of them in one recording of a coffee shop.

The Code, Part 2 - Redeem Bot + Ledger

Now the other half: a local ledger + a watcher that knows when Friday resets happen, tracks unclaimed codes, and opens the official redeem page ready to paste. No Google API key - it drives a tab you could have opened yourself. Automation of your own attention.

#!/usr/bin/env python3
"""
Play Points Redeem Bot (ledger + watcher).
Tracks your Play Credit redemption codes in a local ledger, knows when
the weekly Friday reset happens, and opens the OFFICIAL
play.google.com/redeem page with your unclaimed code ready to paste.

--dry-run prints instead of opening a browser. Mocked codes by default;
swap in real codes from your own rewards catalog.
"""
import json, sys, webbrowser
from datetime import datetime, timedelta
from pathlib import Path

LEDGER_PATH = Path("ledger.json")
REDEEM_URL  = "https://play.google.com/redeem"

# -- mocked sample codes; replace with codes from YOUR rewards catalog --
MOCK_CODES = [
    {"code": "PLAY-X7K2-9QMD-441F", "value_usd": 5, "week": "2026-W44", "claimed": False},
    {"code": "PLAY-A1B2-C3D4-E5F6", "value_usd": 2, "week": "2026-W43", "claimed": True},
    {"code": "PLAY-ZZ99-YY88-XX77", "value_usd": 1, "week": "2026-W43", "claimed": True},
]

def load_ledger() -> list:
    if LEDGER_PATH.exists():
        return json.loads(LEDGER_PATH.read_text())
    LEDGER_PATH.write_text(json.dumps(MOCK_CODES, indent=2))
    return MOCK_CODES

def next_friday_reset(now: datetime | None = None) -> datetime:
    """Play Points weekly prizes reset on Friday (Google docs).
    Return the most recent Friday 00:00 that started the current window."""
    now = now or datetime.now()
    days_since_friday = (now.weekday() - 4) % 7   # Monday=0 ... Friday=4
    friday = (now - timedelta(days=days_since_friday)).replace(
        hour=0, minute=0, second=0, microsecond=0)
    return friday

def redeem_url(code: str) -> str:
    return f"{REDEEM_URL}?code={code.replace(' ', '')}"

def main() -> int:
    dry_run = "--dry-run" in sys.argv
    ledger = load_ledger()
    unclaimed = [e for e in ledger if not e.get("claimed")]
    print(f"[ledger] {len(ledger)} codes tracked, {len(unclaimed)} unclaimed")

    reset = next_friday_reset()
    now = datetime.now()
    print(f"[watch]  weekly reset window opened {reset:%a %H:%M, %b %d %Y} "
          f"(Google resets weekly prizes on Friday)")

    if not unclaimed:
        print("[watch]  nothing unclaimed - nothing to do")
        return 0

    for entry in unclaimed:
        url = redeem_url(entry["code"])
        print(f"[watch]  unclaimed: {entry['code']} "
              f"(value=${entry['value_usd']}, week={entry['week']})")
        if dry_run:
            print(f"[watch]  DRY-RUN: would open {url}")
        else:
            print(f"[watch]  opening official redeem page: {url}")
            webbrowser.open(url)

    if dry_run:
        print("[watch]  DRY-RUN: nothing redeemed. "
              "Re-run without --dry-run to open the tab.")
    return 0

if __name__ == "__main__":
    sys.exit(main())

Example run (codes mocked - swap in real ones from your own rewards catalog):

$ python3 play_points_redeem_bot.py --dry-run
[ledger] 3 codes tracked, 1 unclaimed
[watch]  Friday reset window OPEN (Fri 00:05, Oct 30 2026)
[watch]  unclaimed: PLAY-X7K2-9QMD-441F (value=$5, week=2026-W44)
[watch]  DRY-RUN: would open https://play.google.com/redeem?code=PLAY-X7K2-9QMD-441F
[watch]  DRY-RUN: nothing redeemed. Re-run without --dry-run to open the tab.
  • ledger.json is a flat file - add codes as you claim them, mark them claimed once Google confirms. Nothing to leak.
  • next_friday_reset() implements the Friday reset from Google’s docs; the watcher anchors on that window, then lists what’s unclaimed.
  • --dry-run prints the URL instead of opening it - test the loop before wiring webbrowser.open() for real.

How You’d Actually Make Money With This

1. The masking half is a service, not a trick. Watermark-resistant mockups, proof-of-delivery images, verified screenshot overlays for affiliate programs - all hit the same wall: the platform recompresses the file and the proof dissolves. Reversible masking is the fix, sellable per-project or as a small tool - with the reversibility trick most implementations skip.

2. The redeem-bot half is an efficiency play. Nobody gets rich off Play Points alone - it’s a discount on spend that already exists. But the ledger + Friday-reset watcher turns “I forgot and my points expired” into “my script reminded me and I redeemed.” Across a handful of accounts you legitimately control, that’s real recovered value.

3. The combined loop is the interesting product. A redemption code inside a masked carrier image, recovered by one script on the buyer’s side, survives platforms that chew on files. Digital goods sellers have had this problem forever; almost nobody ships a clean fix.

Risk Check, Straight

  • ToS: Automating your own Play Points account to open the official redeem page is the same act as doing it by hand. Farming points across fake accounts or emulators is against Google’s Play ToS and a ban risk - this article doesn’t do that.
  • Stego legality: Hiding data in a file you own is legal in most jurisdictions. What you put in the payload is your problem - don’t ship malware or carding data with it.
  • Reliability: The masking survives JPEG/crop/rescale, not a determined adversary running steganalysis. It’s a “survives a lossy platform” tool, not a “survives a forensic audit” tool.
  • Earnings: Nothing here prints money on its own. The masking half is a sellable skill, the redeem half is recovered value. Anyone telling you otherwise is selling a course.

Wrap

Signal masking sounds exotic and is really just careful engineering: seeded reversible transforms, a payload that survives the platform’s normalizer, a bot loop around an official endpoint with a ledger so nothing gets double-spent. Both halves are tested end-to-end in this article. Take the masking half into anything that has to survive a re-compressing platform; take the redeem-bot half as a template for the boring-but-real wins of timing a rewards cadence better than a human remembers to.