This is not particularly elegant but should do the trick:
ALTER TABLE myTable ADD col_hash AS HASHBYTES('MD5',
ISNULL(CAST(col1 as varbinary(max)),0x00) + ISNULL(CAST(col2 as varbinary(max)),0x00) +
ISNULL(CAST(col3 as varbinary(max)),0x00) + ISNULL(CAST(col4 as varbinary(max)),0x00) +
ISNULL(CAST(col5 as varbinary(max)),0x00) + ISNULL(CAST(col6 as varbinary(max)),0x00) +
ISNULL(CAST(col7 as varbinary(max)),0x00) + ISNULL(CAST(col8 as varbinary(max)),0x00) +
ISNULL(CAST(col9 as varbinary(max)),0x00) + ISNULL(CAST(col10 as varbinary(max)),0x00) +
ISNULL(CAST(col11 as varbinary(max)),0x00) + ISNULL(CAST(col12 as varbinary(max)),0x00) +
ISNULL(CAST(col13 as varbinary(max)),0x00) + ISNULL(CAST(col14 as varbinary(max)),0x00) +
ISNULL(CAST(col15 as varbinary(max)),0x00) + ISNULL(CAST(col16 as varbinary(max)),0x00) +
ISNULL(CAST(col17 as varbinary(max)),0x00) + ISNULL(CAST(col18 as varbinary(max)),0x00) +
ISNULL(CAST(col19 as varbinary(max)),0x00) + ISNULL(CAST(col20 as varbinary(max)),0x00) +
ISNULL(CAST(col21 as varbinary(max)),0x00) + ISNULL(CAST(col22 as varbinary(max)),0x00) +
ISNULL(CAST(col23 as varbinary(max)),0x00) + ISNULL(CAST(col24 as varbinary(max)),0x00) +
ISNULL(CAST(col25 as varbinary(max)),0x00) + ISNULL(CAST(col26 as varbinary(max)),0x00) +
ISNULL(CAST(col27 as varbinary(max)),0x00) + ISNULL(CAST(col28 as varbinary(max)),0x00) +
ISNULL(CAST(col29 as varbinary(max)),0x00) + ISNULL(CAST(col30 as varbinary(max)),0x00));
ALTER TABLE myTable ADD CONSTRAINT UNQ_col_hash UNIQUE(col_hash);
If all of your columns are declared NOT NULL then you can just CAST(colXX as varbinary(max)). The combination of values should hash to a unique MD5 value which is 128 bits. If you are concerned about hash collisions, simply add a 2nd hashed column like this and use SHA or some other supported hash algorithm, and create a unique constraint on both of those columns.
Edit: F------k, I just noticed you said the table schema can't be changed. Let me think a bit.
Edit 2: I set up a test using an indexed view that prevents duplicates:
SET ANSI_NULLS,ANSI_PADDING,ANSI_WARNINGS,ARITHABORT,CONCAT_NULL_YIELDS_NULL,QUOTED_IDENTIFIER ON;
GO
SET NUMERIC_ROUNDABORT OFF;
GO
create table dbo.A(a varchar(5) not null, b varchar(10) not null);
GO
create view dbo.ind(a,b,hash_col) with schemabinding AS
SELECT a, b, HASHBYTES('MD5',cast(a as varbinary(5))+cast(b as varbinary(10)))
from dbo.A;
GO
create unique clustered index ix on dbo.ind(hash_col);
insert dbo.A(a,b) values('a','b');
insert dbo.A(a,b) values('a','b'); -- this insert fails, violates uniqueness in indexed view
I'm not sure if you can cast as varbinary(max) and have it work properly, since you're not using max types it's probably better to cast to fixed binary anyway. Note that my columns are declared NOT NULL, if yours are not you'll need to wrap them in ISNULL() like in my earlier example.
You can read more about indexed views here:
https://docs.microsoft.com/en-us/sql/relational-databases/views/create-indexed-views
Edit 3: One other thing I noticed, since this casts to binary values it is automatically case-sensitive, regardless of which collation you're using. If you want case-insensitive uniqueness you'll have to do CAST(UPPER(col) as varbinary(...)) inside the HASHBYTES() function.
Edit 4: One last thought before I sleep:
create view dbo.ind(a,b,hash_col) with schemabinding AS
SELECT a, b, HASHBYTES('MD5',cast(a as varbinary(5))+0x00+cast(b as varbinary(10))+0x00)
from dbo.A;
GO
This avoids a problem with concatenating 'ab'+'c' vs. 'a'+'bc' being considered dupes. You'd have to concatenate 0x00 between each column in the HASHBYTES() expression.